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
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ jobs:
mkdir -p "$LOG_DIR"
./scripts/run-uvm-browser-worker-matrix.sh \
--smoke \
--known-failure pinned-wasm-uvm-abort \
--retries 3 \
--log-dir "$LOG_DIR"

Expand Down
8 changes: 8 additions & 0 deletions artifacts/tutorial/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,14 @@ BMC-LTL-NOT (25, 47, 48). Still do not publish; 0033 is in review.
a runtime `UVM/DPI/REGEX` error. `mox-verilog.wasm` itself aborts while compiling uvm-core (log:
`ci/ci-36034279627-failed.log`). Recheck it against the rebuilt WASM before planning any DPI bridge change.

**Follow-up CI disposition (October 1, 2026).** The released `mox-verilog.wasm` is still the exact stale artifact
(`eb6badaf759c72dd4a7dff97d025e58dea75ea0863c2461464219bee69ec65a2`) that produces the
`uvm_config_db_implementation.svh:375` warning followed by `Aborted()`. Current-tip Mox WASM built from the
`eb9d0b6cf5d` lineage avoids that abort but does not finish the same browser-worker UVM compile within 600 seconds,
so it is not safe to repin. The ordinary `ci` reporting smoke now uses an explicit hash- and log-signature-checked
quarantine; `uvm-nightly` remains strict and reports the parity failure. A qualified WASM rebuild or Mox parity fix is
still required before removing the quarantine.

## Left open (documentation and a legacy harness; no behaviour change, so no test)
- B14: `scripts/test-all-lessons.mjs` predates mox-run and accepts any `PASS` line. Retire it in favour of
`e2e/qa-all-lessons.spec.js`, or port it to mox-run and require a final PASS with exit 0.
Expand Down
29 changes: 29 additions & 0 deletions scripts/run-uvm-browser-worker-matrix.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@ Options:
--lessons <csv> Comma-separated lesson list
--retries <n> Retry count per lesson (default: 3)
--log-dir <path> Directory for per-lesson logs
--known-failure <id> Allow only the named, hash-checked known failure
EOF
}

retries="${UVM_MATRIX_RETRIES:-3}"
log_dir="${UVM_MATRIX_LOG_DIR:-}"
known_failure=""
declare -a selected_lessons=()

while (($# > 0)); do
Expand Down Expand Up @@ -82,6 +84,15 @@ while (($# > 0)); do
log_dir="$2"
shift 2
;;
--known-failure)
if (($# < 2)); then
echo "error: --known-failure requires an id" >&2
usage
exit 2
fi
known_failure="$2"
shift 2
;;
-h|--help)
usage
exit 0
Expand All @@ -103,6 +114,17 @@ if ((${#selected_lessons[@]} == 0)); then
selected_lessons=("${DEFAULT_LESSONS[@]}")
fi

if [[ -n "$known_failure" && "$known_failure" != "pinned-wasm-uvm-abort" ]]; then
echo "error: unknown --known-failure id: $known_failure" >&2
exit 2
fi

if [[ "$known_failure" == "pinned-wasm-uvm-abort" &&
("${#selected_lessons[@]}" -ne 1 || "${selected_lessons[0]}" != "reporting") ]]; then
echo "error: pinned-wasm-uvm-abort is only valid for the reporting smoke" >&2
exit 2
fi

if [[ -z "$log_dir" ]]; then
log_dir="$(mktemp -d)"
else
Expand Down Expand Up @@ -132,6 +154,13 @@ for lesson in "${selected_lessons[@]}"; do
continue
fi

if [[ "$known_failure" == "pinned-wasm-uvm-abort" ]] &&
node scripts/uvm-known-failure.mjs "$log_file" static/mox/mox-verilog.wasm; then
echo "KNOWN FAILURE $lesson: pinned mox-verilog WASM abort at uvm_config_db_implementation.svh:375"
passed=1
break
fi

echo "FAIL $lesson (non-transient)"
sed -n '1,200p' "$log_file"
failures=$((failures + 1))
Expand Down
53 changes: 53 additions & 0 deletions scripts/uvm-known-failure.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { createHash } from 'node:crypto';
import { readFile } from 'node:fs/promises';
import path from 'node:path';
import { pathToFileURL } from 'node:url';

export const PINNED_MOX_VERILOG_WASM_SHA256 =
'eb6badaf759c72dd4a7dff97d025e58dea75ea0863c2461464219bee69ec65a2';

const PINNED_UVM_ABORT_MARKERS = [
'mox-verilog --resource-guard=false',
'--uvm-path /mox/uvm-core',
'uvm_config_db_implementation.svh:375:26: warning: unknown character escape sequence',
'Aborted()'
];

export function isPinnedUvmAbort({ log, wasmSha256 }) {
return (
wasmSha256 === PINNED_MOX_VERILOG_WASM_SHA256 &&
PINNED_UVM_ABORT_MARKERS.every((marker) => log.includes(marker))
);
}

export async function sha256File(filePath) {
const contents = await readFile(filePath);
return createHash('sha256').update(contents).digest('hex');
}

async function main() {
const [logPath, wasmPath] = process.argv.slice(2);
if (!logPath || !wasmPath) {
console.error('usage: node scripts/uvm-known-failure.mjs <log> <mox-verilog.wasm>');
process.exitCode = 2;
return;
}

const [log, wasmSha256] = await Promise.all([
readFile(logPath, 'utf8'),
sha256File(wasmPath)
]);

if (!isPinnedUvmAbort({ log, wasmSha256 })) {
process.exitCode = 1;
return;
}

console.log(
`recognized pinned-WASM UVM abort (${path.basename(wasmPath)} sha256=${wasmSha256})`
);
}

if (process.argv[1] && import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) {
await main();
}
53 changes: 53 additions & 0 deletions src/runtime/uvm-ci-quarantine.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { describe, expect, it } from 'vitest';
import { readFileSync } from 'node:fs';
import path from 'node:path';
import {
isPinnedUvmAbort,
PINNED_MOX_VERILOG_WASM_SHA256
} from '../../scripts/uvm-known-failure.mjs';

const CI_WORKFLOW = readFileSync(
path.resolve(process.cwd(), '.github/workflows/ci.yml'),
'utf8'
);
const NIGHTLY_WORKFLOW = readFileSync(
path.resolve(process.cwd(), '.github/workflows/uvm-nightly.yml'),
'utf8'
);

const PINNED_UVM_ABORT_LOG = [
'$ mox-verilog --resource-guard=false --ir-llhd --uvm-path /mox/uvm-core',
'/mox/uvm-core/src/base/uvm_config_db_implementation.svh:375:26: warning: unknown character escape sequence',
'Aborted()'
].join('\n');

describe('UVM CI known-failure quarantine', () => {
it('recognizes only the pinned WASM UVM abort signature', () => {
expect(
isPinnedUvmAbort({
log: PINNED_UVM_ABORT_LOG,
wasmSha256: PINNED_MOX_VERILOG_WASM_SHA256
})
).toBe(true);

expect(
isPinnedUvmAbort({
log: PINNED_UVM_ABORT_LOG,
wasmSha256: 'current-or-unknown-artifact'
})
).toBe(false);

expect(
isPinnedUvmAbort({
log: PINNED_UVM_ABORT_LOG.replace('Aborted()', 'Aborted(OOM)'),
wasmSha256: PINNED_MOX_VERILOG_WASM_SHA256
})
).toBe(false);
});

it('quarantines only the reporting smoke in CI, not nightly parity', () => {
expect(CI_WORKFLOW).toContain('--known-failure pinned-wasm-uvm-abort');
expect(CI_WORKFLOW).toContain('run-uvm-browser-worker-matrix.sh');
expect(NIGHTLY_WORKFLOW).not.toContain('--known-failure');
});
});
Loading