Record independent package and native Windows navigation acceptance

This commit is contained in:
2026-09-12 03:51:26 -07:00
parent 9613cf71aa
commit f5e1c734da
108 changed files with 27991 additions and 0 deletions
@@ -0,0 +1,26 @@
# Packaged repaired navigation trial — preparation only
Root owns GUI input and acceptance. No launcher, oracle, process/module check or package action has been executed during this preparation. This helper uses the future independently reviewed package extraction directly, never the mutable target executable or producer stage. It does not repeat invalid-source repair/recovery tests already covered by the B183 v4 trial.
The candidate is B183EF31…B168848 from source33c6d83, retained historical EFEE server and F456 DLL. Version is 0.2.0-preview.navigation.20260911. The server remains separately sourced. Native acceptance must distinguish this new package trial from the prior source-native v3/v4 trials.
## Binding and future execution
`binding.pending.json` intentionally has no archive/review/extraction values. Once actual package/readback and independent artifact PASS exist, root/release_audit will read them, create binding.json with exact repository-relative .local paths, hashes/size and reviewed extraction, then pin its SHA256 in helper.py. Root reviews the final helper and binding before execution. The helper currently has BINDING_SHA=None and refuses launch. Arbitrary package paths cannot be supplied on the command line.
Admission verifies the binding, actual ZIP bytes, producer and reviewer PASS/hash/size/full file maps, every extracted file, ZIP entry contents and all three binary hashes. A fresh exclusive trial/ contains private profile/Desktop/APPDATA/LOCALAPPDATA/TEMP, screenshots and work. Standard nonsecret Windows paths are inherited explicitly; PATH contains only Windows directories. The package working directory remains the extraction, allowing full-map checks to detect incidental added files. Package contents are never modified by the helper. Initial work is an exact private copy of the pinned valid navigation fixture: four Arcadia files, Unicode path, two activities and one interaction. No baseline oracle is run merely to copy this already pinned fixture.
Future authorized commands from repository cwd, using `C:/Users/User/.cache/codex-runtimes/codex-primary-runtime/dependencies/python/python.exe`:
```text
python .local/navigation-repair-package-native-20260911/helper.py launch
pwsh -NoProfile -File .local/navigation-repair-package-native-20260911/loaded-modules.ps1
python .local/navigation-repair-package-native-20260911/helper.py saved --label navigation-final-saved --after-visible-save
python .local/navigation-repair-package-native-20260911/helper.py closed --observed-absent
```
These commands have not been executed. Replace python with the absolute bundled executable. Root first opens trial/work/project.arcadia through the real file dialog, exercises F12, References and Back, edits then restores using Undo/Apply as intended, explicitly saves the baseline, and observes success. Only then is saved allowed. It preserves an exact source checkpoint and requires all four raw files equal the pinned baseline before running the complete same oracle967. The oracle gets only the package directory plus Windows PATH for F456 resolution. Raw stdout/stderr/exit and before/after package guards are retained. Any unexpected package addition/removal/change writes the exact delta before refusal. This is saved model/source evidence, not a synthetic assertion that GUI actions happened.
Root closes normally, observes the window absent, then invokes closed. The helper checks the original PID plus creation identity is absent (a reused PID is distinguished), and checks the entire ZIP/package map again. It does not close/kill any process or fabricate a numeric exit code. The optional loaded-modules.ps1 is a separate read-only query of the exact PID/path/creation identity; it records paths/hashes and flags modules outside Windows or the reviewed package. It does not operate the GUI or launch a server.
All operations refuse existing receipts/trials. Do not delete or overwrite a failed trial; retain evidence and prepare a separately reviewed trial if needed. No compilation, source edits, publishing, tags or WSL operations are included. Old contextual and navigation trials/helpers remain untouched.
@@ -0,0 +1,12 @@
{
"status": "PENDING",
"source_commit": "33c6d83e9ba9a5b1310b1b627d7c40affcbcf15c",
"archive_path": null,
"archive_sha256": null,
"archive_bytes": null,
"review_path": null,
"review_sha256": null,
"producer_readback_path": null,
"producer_readback_sha256": null,
"package_path": null
}
@@ -0,0 +1,25 @@
{
"scope": "Unbound packaged native helper draft; no helper/module/oracle/package execution",
"files": [
{
"path": "helper.py",
"sha256": "01285a8bdf0efe4b7dff6de6136fdfe22db8f9807c8b29f69c8384bbb9ddffa6",
"bytes": 12804
},
{
"path": "loaded-modules.ps1",
"sha256": "39527416b3043de1a360788436a330c5293b8941a3317defad6e2c82e6ee31fe",
"bytes": 2889
},
{
"path": "README.md",
"sha256": "0ab3178d5d43fe4e87d96882cd1a71a451eb7fc4c894d6db4bd8e0d7af3182c2",
"bytes": 4176
},
{
"path": "binding.pending.json",
"sha256": "1c39142ec0e11067a4ff12911156741b73c3c305148a38fee861320dd1eedf7e",
"bytes": 306
}
]
}
@@ -0,0 +1,266 @@
"""Packaged navigation trial; GUI input and release acceptance belong to root.
No execution is admitted until binding.json is completed and its SHA is pinned
after independent artifact review. Nothing here operates the GUI or compiles.
"""
import argparse
import ctypes
from ctypes import wintypes
from datetime import datetime, timezone
import hashlib
import json
import os
from pathlib import Path, PurePosixPath
import re
import shutil
import subprocess
import sys
import zipfile
ROOT = Path(__file__).resolve().parents[2]
BASE = Path(__file__).resolve().parent
TRIAL = BASE / 'trial'
BINDING_SHA = None # Intentionally refuses before the actual package review.
SOURCE = '33c6d83e9ba9a5b1310b1b627d7c40affcbcf15c'
NAME = 'ArcadiaStudio-0.2.0-preview.navigation.20260911-x86_64-pc-windows-gnullvm'
EXPECTED = {
'arcadia-studio.exe': 'b183ef31f16b3986538b3f2aba8435eab45978635c47f99ca01be6e72b168848',
'arcadia-server.exe': 'efeeb89c0d2e0f93df4472cb3e9f48b2b722a37ae1043c90a5a56f2e845fe665',
'libunwind.dll': 'f45604a12e8bcd839fd86f667c1be1cc7c4f9da2b3c69ff381ac708f0e1ae7d4',
}
FIXTURES = ROOT / '.local/text-navigation-native-20260911-preparation'
FIXTURE_SHA = 'edd4157fc31823f4494dee91862728b87f12ef51c49b8d1fd86a954bc9ecc1ed'
ORACLE = ROOT / '.local/staged-source-oracle-20260911/staged-source-authoring-contract.exe'
ORACLE_SHA = '967d9ba3c6fb3a7efb410833903ec94556ca2d48a67d5072c8bb160f40a00f9c'
def now():
return datetime.now(timezone.utc).isoformat()
def ordinary(path):
path = Path(path).absolute()
for p in (path, *path.parents):
if p.exists():
assert not p.is_symlink() and not (getattr(p.lstat(), 'st_file_attributes', 0) & 0x400), str(p)
return path
def sha(path):
with ordinary(path).open('rb') as stream:
return hashlib.file_digest(stream, 'sha256').hexdigest()
def load(path):
return json.loads(ordinary(path).read_text(encoding='utf-8-sig'))
def record(path, value):
ordinary(path)
with path.open('x', encoding='utf-8', newline='\n') as out:
json.dump(value, out, ensure_ascii=False, indent=2)
out.write('\n')
def relative(name):
p = PurePosixPath(name)
assert name == p.as_posix() and not p.is_absolute() and p.parts
assert all(x not in ('.', '..') for x in p.parts)
assert not any(c in name for c in '\\:\r\n')
return name
def local(name):
p = ordinary(ROOT / relative(name))
assert p.resolve().is_relative_to(ROOT / '.local')
return p
def inventory(folder):
ordinary(folder)
found = {}
for p in folder.rglob('*'):
ordinary(p)
if p.is_file():
found[p.relative_to(folder).as_posix()] = sha(p)
assert len({p.casefold() for p in found}) == len(found)
return found
def copy_exact(source, destination):
before = inventory(source)
assert not destination.exists()
shutil.copytree(source, destination)
assert inventory(source) == inventory(destination) == before
return before
def environment():
parent = {k.upper(): v for k, v in os.environ.items()}
standard = {k: parent[k.upper()] for k in ('SystemRoot', 'SystemDrive', 'ProgramData', 'ALLUSERSPROFILE', 'PUBLIC')}
assert all(v and '%' not in v for v in standard.values())
system = standard['SystemRoot']
return {**standard, 'WINDIR': system, 'PATH': system + '\\System32;' + system,
'USERPROFILE': str(TRIAL / 'profile'), 'APPDATA': str(TRIAL / 'profile/roaming'),
'LOCALAPPDATA': str(TRIAL / 'profile/local'), 'TEMP': str(TRIAL / 'tmp'), 'TMP': str(TRIAL / 'tmp')}
def process_identity(pid):
"""Read-only process query; invalid PID means absent, access errors refuse."""
api = ctypes.WinDLL('kernel32', use_last_error=True)
api.OpenProcess.argtypes = [wintypes.DWORD, wintypes.BOOL, wintypes.DWORD]
api.OpenProcess.restype = wintypes.HANDLE
api.CloseHandle.argtypes = [wintypes.HANDLE]
api.GetProcessTimes.argtypes = [wintypes.HANDLE] + [ctypes.POINTER(wintypes.FILETIME)] * 4
api.GetProcessTimes.restype = wintypes.BOOL
api.QueryFullProcessImageNameW.argtypes = [wintypes.HANDLE, wintypes.DWORD, wintypes.LPWSTR, ctypes.POINTER(wintypes.DWORD)]
api.QueryFullProcessImageNameW.restype = wintypes.BOOL
handle = api.OpenProcess(0x1000, False, pid)
if not handle:
error = ctypes.get_last_error()
assert error == 87, f'Process query failed: {error}'
return None
try:
created, exited, kernel, user = (wintypes.FILETIME() for _ in range(4))
assert api.GetProcessTimes(handle, ctypes.byref(created), ctypes.byref(exited), ctypes.byref(kernel), ctypes.byref(user))
buffer, count = ctypes.create_unicode_buffer(32768), wintypes.DWORD(32768)
assert api.QueryFullProcessImageNameW(handle, 0, buffer, ctypes.byref(count))
return {'path': str(Path(buffer.value).resolve()), 'creation_filetime': (created.dwHighDateTime << 32) | created.dwLowDateTime}
finally:
api.CloseHandle(handle)
def admission(verify_inventory=True):
assert BINDING_SHA and sha(BASE / 'binding.json') == BINDING_SHA, 'Package binding is pending or changed.'
binding = load(BASE / 'binding.json')
assert binding['status'] == 'READY' and binding['source_commit'] == SOURCE
archive, review_path, producer_path, package = (local(binding[k]) for k in ('archive_path', 'review_path', 'producer_readback_path', 'package_path'))
assert archive.name == NAME + '.zip' and package.name == NAME
assert package.resolve() != (producer_path.parent / 'packages' / NAME).resolve(), 'Use independent extraction, not producer stage.'
assert sha(archive) == binding['archive_sha256'] and archive.stat().st_size == binding['archive_bytes']
assert sha(review_path) == binding['review_sha256'] and sha(producer_path) == binding['producer_readback_sha256']
review, producer = load(review_path), load(producer_path)
assert review['status'] == producer['status'] == 'PASS'
assert review['archive']['sha256'] == producer['archive_sha256'] == binding['archive_sha256']
assert review['archive']['bytes'] == producer['archive_bytes'] == binding['archive_bytes']
assert Path(review['archive']['path']).resolve() == archive.resolve()
expected = review['archive']['files']
assert expected == {p: v['sha256'] for p, v in producer['files'].items()}
assert review['archive']['file_count'] == producer['file_count'] == len(expected)
if verify_inventory:
assert inventory(package) == expected
for p, h in EXPECTED.items():
assert expected[p] == h
zipped = {}
with zipfile.ZipFile(archive) as z:
for item in z.infolist():
assert item.filename.startswith(NAME + '/') and not item.is_dir()
p = relative(item.filename[len(NAME) + 1:])
assert p not in zipped
zipped[p] = hashlib.sha256(z.read(item)).hexdigest()
assert zipped == expected
return binding, package, expected
def fixture():
assert sha(FIXTURES / 'fixture-manifest.json') == FIXTURE_SHA
expected = {e['path'].removeprefix('valid-baseline/'): e['sha256'] for e in load(FIXTURES / 'fixture-manifest.json') if e['path'].startswith('valid-baseline/')}
assert len(expected) == 4 and inventory(FIXTURES / 'valid-baseline') == expected
assert sha(ORACLE) == ORACLE_SHA
return FIXTURES / 'valid-baseline', expected
def launch():
assert not TRIAL.exists(), 'Preserve old trial; never overwrite.'
binding, package, expected = admission()
baseline, files = fixture()
TRIAL.mkdir()
for folder in ('profile/local', 'profile/roaming', 'profile/Desktop', 'tmp', 'screenshots', 'checkpoints'):
(TRIAL / folder).mkdir(parents=True)
assert copy_exact(baseline, TRIAL / 'work') == files
record(TRIAL / 'package-before.json', expected)
record(TRIAL / 'source-before.json', files)
record(TRIAL / 'admission.json', {'atUtc': now(), 'binding_sha256': BINDING_SHA, 'binding': binding, 'fixture_sha256': FIXTURE_SHA, 'scope': 'Artifact/fixture admission, not native acceptance.'})
env = environment()
startup = subprocess.STARTUPINFO()
startup.dwFlags |= subprocess.STARTF_USESHOWWINDOW
startup.wShowWindow = 0
with (TRIAL / 'stdout.log').open('xb') as out, (TRIAL / 'stderr.log').open('xb') as err:
process = subprocess.Popen([str(package / 'arcadia-studio.exe')], cwd=package, env=env, stdout=out, stderr=err, startupinfo=startup)
# Preserve PID immediately even if a subsequent read-only identity query fails.
receipt = {'atUtc': now(), 'pid': process.pid, 'package': str(package), 'environment': env,
'binding_sha256': BINDING_SHA, 'source': str(TRIAL / 'work/project.arcadia'), 'scope': 'Identified packaged GUI launched; native acceptance pending.'}
record(TRIAL / 'launch.json', receipt)
identity = process_identity(process.pid)
assert identity and Path(identity['path']) == (package / 'arcadia-studio.exe').resolve()
record(TRIAL / 'process-identity.json', identity)
print(json.dumps(receipt, ensure_ascii=False, indent=2))
def package_guard(label):
binding, package, expected = admission(verify_inventory=False)
launch_receipt = load(TRIAL / 'launch.json')
assert launch_receipt['binding_sha256'] == BINDING_SHA and Path(launch_receipt['package']).resolve() == package.resolve()
assert load(TRIAL / 'package-before.json') == expected
actual = inventory(package)
unchanged = actual == expected
record(TRIAL / (label + '-package.json'), {'atUtc': now(), 'archive_sha256': binding['archive_sha256'], 'files': actual,
'added': sorted(actual.keys() - expected.keys()), 'removed': sorted(expected.keys() - actual.keys()),
'changed': sorted(p for p in actual.keys() & expected.keys() if actual[p] != expected[p]),
'completeInventoryUnchanged': unchanged})
assert unchanged, 'Package changed; exact delta receipt preserved.'
return package
def saved(args):
assert args.after_visible_save, 'Root must observe successful Save first.'
assert re.fullmatch('[a-z0-9][a-z0-9-]{0,79}', args.label)
folder = TRIAL / 'checkpoints' / args.label
assert not folder.exists()
package = package_guard(args.label)
baseline, expected = fixture()
folder.mkdir()
actual = copy_exact(TRIAL / 'work', folder / 'sources')
record(folder / 'sources.json', actual)
assert actual == expected, 'Saved exact baseline files differ; preserve and inspect.'
env = environment()
env['PATH'] = str(package) + ';' + env['PATH']
command = [str(ORACLE), 'same', str(baseline / 'project.arcadia'), str(folder / 'sources/project.arcadia')]
result = subprocess.run(command, cwd=folder, env=env, capture_output=True)
(folder / 'stdout.log').write_bytes(result.stdout)
(folder / 'stderr.log').write_bytes(result.stderr)
record(folder / 'result.json', {'atUtc': now(), 'command': command, 'exitCode': result.returncode, 'oracle_sha256': ORACLE_SHA,
'scope': 'Saved disk/model oracle after root-observed Save; no independent UI assertion.'})
assert result.returncode == 0
package_guard(args.label + '-after-oracle')
print(json.dumps({'action': 'saved', 'oracle_exit': 0, 'source_files': len(actual)}))
def closed(args):
assert args.observed_absent, 'Root must first observe the GUI/window absent.'
launch_receipt = load(TRIAL / 'launch.json')
current = process_identity(launch_receipt['pid'])
original = load(TRIAL / 'process-identity.json')
assert current is None or current['creation_filetime'] != original['creation_filetime'], 'Original GUI process remains present.'
package = package_guard('after-close')
record(TRIAL / 'closed.json', {'atUtc': now(), 'pid': launch_receipt['pid'], 'originalProcessAbsent': True,
'pidReused': current is not None, 'completePackageUnchanged': True,
'scope': 'Root-observed window absence plus read-only process identity and package check; no numeric exit code observed.'})
print(json.dumps({'action': 'closed', 'package': str(package), 'result': 'PASS'}))
if __name__ == '__main__':
sys.stdout.reconfigure(encoding='utf-8')
sys.stderr.reconfigure(encoding='utf-8')
parser = argparse.ArgumentParser()
parser.add_argument('action', choices=('launch', 'saved', 'closed'))
parser.add_argument('--label')
parser.add_argument('--after-visible-save', action='store_true')
parser.add_argument('--observed-absent', action='store_true')
args = parser.parse_args()
if args.action == 'launch':
launch()
elif args.action == 'saved':
saved(args)
else:
closed(args)
@@ -0,0 +1,44 @@
# Optional read-only process inventory. Never launches, closes or controls a GUI.
#Requires -Version 7.0
$ErrorActionPreference = 'Stop'
$trialPath = Join-Path $PSScriptRoot 'trial'
$resultPath = Join-Path $trialPath 'loaded-modules.json'
if (Test-Path -LiteralPath $resultPath) { throw 'Preserve existing module receipt.' }
$launch = Get-Content -LiteralPath (Join-Path $trialPath 'launch.json') -Raw | ConvertFrom-Json
$identity = Get-Content -LiteralPath (Join-Path $trialPath 'process-identity.json') -Raw | ConvertFrom-Json
$before = Get-Content -LiteralPath (Join-Path $trialPath 'package-before.json') -Raw | ConvertFrom-Json
$receipt = [ordered]@{ atUtc = [DateTime]::UtcNow.ToString('o'); pid = $launch.pid; status = 'PENDING'; modules = @(); scope = 'Point-in-time loaded modules of the exact launched process; no GUI action or universal runtime dependency claim.' }
try {
$guiProcess = Get-Process -Id $launch.pid -ErrorAction Stop
if (-not [string]::Equals($guiProcess.Path, $identity.path, [StringComparison]::OrdinalIgnoreCase) -or
$guiProcess.StartTime.ToUniversalTime().ToFileTimeUtc() -ne $identity.creation_filetime) {
throw 'PID no longer identifies the original launch.'
}
$receipt.creation_filetime = $identity.creation_filetime
$systemRoot = [IO.Path]::GetFullPath($launch.environment.SystemRoot).TrimEnd('\') + '\'
$packageRoot = [IO.Path]::GetFullPath($launch.package).TrimEnd('\') + '\'
$items = foreach ($module in $guiProcess.Modules) {
$full = [IO.Path]::GetFullPath($module.FileName)
$inWindows = $full.StartsWith($systemRoot, [StringComparison]::OrdinalIgnoreCase)
$inPackage = $full.StartsWith($packageRoot, [StringComparison]::OrdinalIgnoreCase)
$hash = (Get-FileHash -LiteralPath $full -Algorithm SHA256).Hash.ToLowerInvariant()
if ($inPackage) {
$relative = $full.Substring($packageRoot.Length).Replace('\', '/')
$recorded = $before.PSObject.Properties[$relative]
if (-not $recorded -or $recorded.Value -cne $hash) { throw "Package module differs: $relative" }
}
[ordered]@{ name = $module.ModuleName; path = $full; sha256 = $hash; windowsPath = $inWindows; packagePath = $inPackage }
}
$receipt.modules = @($items)
if (-not $receipt.modules.Count) { throw 'No modules observed.' }
$unexpected = @($items | Where-Object { -not $_.windowsPath -and -not $_.packagePath })
$receipt.unexpected = $unexpected
if ($unexpected.Count) { throw 'Unexpected non-Windows, non-package module; inspect receipt.' }
$receipt.status = 'PASS'
} catch {
$receipt.status = 'FAIL'
$receipt.error = $_.ToString()
} finally {
[IO.File]::WriteAllText($resultPath, ($receipt | ConvertTo-Json -Depth 10) + "`n", [Text.UTF8Encoding]::new($false))
}
if ($receipt.status -ne 'PASS') { throw $receipt.error }