Summary
test-files/test_gap_object_methods.ts baseline parity failure (one of the 3 in CLAUDE.md). Filing as a tracked issue.
Symptom
Specifically: mutations against frozen / sealed / non-extensible objects, and writes to defineProperty(... writable:false) properties, don't throw in strict mode. Node prints the "threw" branch; perry's try/catch never fires, so 5 lines of expected output are missing:
< defineProperty write threw (strict mode)
< freeze write threw
< freeze add threw
< sealed add threw
< preventExtensions add threw
Perry silently allows the mutation (the read-back values are also not what Node shows, since the writes succeed).
Reproducer
"use strict";
const obj: Record<string, unknown> = {};
Object.defineProperty(obj, "readOnly", {
value: 42,
writable: false,
enumerable: true,
configurable: false,
});
try {
(obj as any).readOnly = 100; // should throw in strict
console.log("did NOT throw");
} catch {
console.log("threw — correct");
}
Node strict-mode path → threw — correct. Perry → did NOT throw.
Same shape for Object.freeze(obj); obj.x = 1, Object.seal(obj); obj.added = 2, Object.preventExtensions(obj); obj.added = 3.
Probable scope
The runtime's js_object_set_field_by_name path (and its numeric-index sibling) either has no frozen/sealed/preventExtensions check, or has the check but doesn't throw — silently no-ops. CLAUDE.md mentions a defineProperty issue at #450 (defineProperty accessor this) but that's a different gap. This one's about strict-mode-throw semantics.
Environment
- Perry
0.5.710
- macOS arm64 / 26.4
- Surfaced by
scripts/release_sweep.sh tier 2 (parity, baseline failure)
Summary
test-files/test_gap_object_methods.tsbaseline parity failure (one of the 3 in CLAUDE.md). Filing as a tracked issue.Symptom
Specifically: mutations against frozen / sealed / non-extensible objects, and writes to
defineProperty(... writable:false)properties, don't throw in strict mode. Node prints the "threw" branch; perry'stry/catchnever fires, so 5 lines of expected output are missing:Perry silently allows the mutation (the read-back values are also not what Node shows, since the writes succeed).
Reproducer
Node strict-mode path →
threw — correct. Perry →did NOT throw.Same shape for
Object.freeze(obj); obj.x = 1,Object.seal(obj); obj.added = 2,Object.preventExtensions(obj); obj.added = 3.Probable scope
The runtime's
js_object_set_field_by_namepath (and its numeric-index sibling) either has no frozen/sealed/preventExtensions check, or has the check but doesn't throw — silently no-ops. CLAUDE.md mentions adefinePropertyissue at #450 (defineProperty accessor this) but that's a different gap. This one's about strict-mode-throw semantics.Environment
0.5.710scripts/release_sweep.shtier 2 (parity, baseline failure)