Repository navigation
feat(observation): select native profiles by exact platform tuple and record a Linux arm64 candidate - #153
Merged
Conversation
Replace version-only native selection with one exact table keyed by host platform-arch and native version, carrying source commit, initialize platformOs, storage-binding and owner-inspection methods and a pinned executable artifact. Production keeps only the historical darwin-arm64 Codex 0.160.1/0.162.1 rows; there is no version range, libc/arch fallback or cross-platform inheritance, and every Linux tuple stays unsupported. Add Linux machinery for a future evidence-backed row without qualifying one: owned app-server storage binding from that child's /proc entries (direct child, own group, all UIDs, exe inode, stable start time, exact canonical SQLite paths, deleted descriptors refused), a writer-probe --procfs-owner mode that requires /proc/locks to name the lsof owner as the sole exclusive flock holder without changing the generation, and ELF/Mach-O artifact digests within the original deadline. Retained qualifications keep their original platform and a foreign-platform record terminates unsupported before any probe. Tests use injected procfs fakes on every host, a compiled hermetic stand-in for exact artifact pinning, and Linux-only native cases for real procfs/flock, CLI refusal/downgrade and fake-SSH complete/partial results. Refs #130
Add the exact linux-arm64 / Codex 0.162.1 / 092d3acd row pinned to the upstream aarch64-unknown-linux-musl executable digest, with Linux-generated app-server schema evidence and procfs storage/owner inspection. Other Linux architectures, versions and gnu builds remain unsupported. Fix the structural metadata capability check, which used a version-only lookup that became ambiguous once one version had rows on two platforms and refused delivery before effect. A regression test reproduces it. Record the Linux arm64 live evidence: matching artifact and schema hashes, a required bootstrap turn for the new dedicated thread, the pre-effect refusal found by the live run, and one observed client-ID injection with unchanged writer generation and a satisfied independent wait. Refs #130
…tive I/O SSH destination requests could select the qualified linux-arm64 row and enter the app-server path, although SSH-remote observation has no Linux evidence. Profiles now carry sshDestination; Linux rows must refuse it, so a wire request on a Linux row behaves as unsupported: required delivery refuses before effect with zero queue calls and best-effort uses the ordinary queue. Darwin keeps its 0.4.0 destination behaviour. Move the executable digest and the procfs storage binding into an owned worker run under the original remaining budget, refusing at that deadline even if the worker is blocked in kernel I/O. Document the retained-identity boundary (generation binds ps lstart at 1-second resolution; kernel start time and the writer executable are not retained) and fix stale comments. Refs #130
…binds Review found two gaps in the qualified linux-arm64 / Codex 0.162.1 row: only the owned queue child's executable is digest-pinned while the original TUI writer is checked by lsof command/pid/uid and ps lstart, and the writer's kernel start time is not retained across send and independent wait. Closing the second safely needs a reviewed optional ledger field, so the row moves to a non-selectable CANDIDATE_PROFILES entry: every Linux tuple is unsupported again, locally and over SSH. The recorded artifact, schema and injection evidence stay, marked not activated with both blockers. Freeze the activation design in PARITY.md (writer /proc/<pid>/exe binding, optional private observationOwner field, required negatives). Keep the capability and SSH-destination regressions on hermetic tables. Limit the worker comment's hard bound to its supervisor refusal; caller-side realpath/stat/lstat stay synchronous with deadline checks only. Refs #130
The candidate evidence limit now says it does not qualify the row, matching activated: false and its blockers. The linux-arm64 queue schema entry is described as candidate data consumed only by profile selection and tests. The frozen activation design also requires an end-to-end check for a missing destination remote flag and records that procfs lock and device matching was exercised only on ext4. Refs #130
…rding State that the full-suite counts belong to the dd21302 source checkpoint and that later documentation-only heads ran light gates only, and update the validation record date. Describe the worker deadline as a requested group termination with caller refusal; reaping a worker blocked in kernel I/O may happen later. Refs #130
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
abruption
added a commit
that referenced
this pull request
Oct 20, 2026
abruption
added a commit
that referenced
this pull request
Oct 20, 2026
* test(ssh): add operator-invoked deployment receipt and recovery harness Add scripts/deployment-harness.mjs, a repository-only validation harness for the remote deployment ADR. It runs the destination checks (dedicated prefix, root and .receipts trust, staging, probe, mkdir lock, no-replace activation, verification, receipts, rollback, retention, lock breaking) and an operator-side hash-chained run journal as separately invoked commands. It never opens SSH, never installs remotely by itself, never runs during list/send/doctor and leaves the exact-version preflight unchanged. Mutations are dry runs unless --execute; destructive steps also need --confirm-destructive. POSIX only. The harness enforces the step 8 order: destination verification, then the operator doctor and dry-run, then the receipt, then unlock, then the caller switch. It also covers fresh-lock recovery without a receipt, journal-confirmed rollback, corrupt/mismatched/orphan receipts, .receipts trust and unowned or unconfirmable lock overrides. Fix ADR drift for 0.4.0 (version range, handoff preparation after the same preflight, the smol-toml runtime dependency), state the operator check order explicitly, refuse an orphan receipt before activation, and document the harness, its Darwin-local evidence and the unrun Linux, Windows non-admin and Node 22 cells. Record the Darwin-local results in VALIDATION.md; they qualify no destination cell. Refs #23 * docs(ssh): record Linux arm64 deployment harness requalification Record one user-authorized, isolated harness run on a Linux arm64 test host (glibc 2.39, Node 24.18.0, published 0.4.0 installed offline into a new /tmp prefix). It covers the exact operator-check, receipt, unlock and caller-switch order, fresh-lock recovery without a receipt, corrupt/mismatched/orphan receipts, .receipts trust, unknown and unverifiable lock-owner overrides, journal-confirmed rollback and retention, and the activation-table rows. All 89 checked expectations matched; existing user executables stayed byte-identical and the test directory was removed. Scope the ADR and VALIDATION wording to exactly that cell. Linux x64 under the current rules, Node 22 (no binary on either host), Windows (the harness refuses; the only host is administrator-only), races and F6 remain unqualified. Refs #23 * fix(ssh): harden deployment harness input, operator binding and dry runs Address review findings in the #23 validation harness: - dest stage validates the identity file against a closed schema (exact keys and types, version syntax, SHA-256/SHA-512 forms, absolute Node path) and requires the staging name to resolve to a direct child of the root before any write, in dry runs too. Markers use the same schema. - op record accepts an operator dry-run only for the intended no_reachable_target refusal or a normal validated result; transport, host-key, preflight and version refusals no longer pass. - Operator results are bound to what the CLI JSON shows: host equal to op init --dest-host and doctor version equal to the verified install. The --remote-bin used is recorded as remoteBinAttested operator attestation and only checked to name the verified install. - Launcher and native-lock probes run only with --execute: dest probe and dest verify are execute-gated, activate/receipt dry runs classify statically, and unexecuted verify results cannot be recorded. - already_provisioned keeps this run's staging (stagingRetained) for the explicit discard-staging --confirm-destructive step. Add regression tests (traversal/absolute/type/schema identities in dry run and execute, refused transport and preflight dry-runs, host/version /install binding, no launch or probe file in dry runs, retained staging) and record a minimal Linux arm64 rerun with the fixed harness. Cells not rerun keep the earlier harness revision as their evidence. Refs #23 * fix(ssh): bind harness verification to its lock and guard activation Address the second review round of the #23 validation harness: - dest verify --run <run> --execute binds its result to the run, the prefix sentinel ID and the creation time of the run's current lock; op record accepts a verified result only from the recording run's current lock on the same prefix, so an earlier lock's or another run's verification cannot satisfy the operator-check order. - dest activate writes and syncs an activation intent (target and staging) inside the lock before the rename and renames nothing if that write fails; dest unlock checks the intent against the actual target and refuses while it exists without a matching receipt or the intent is unreadable. - dest discard-staging requires --run and a valid staging marker naming that run; markerless leftovers of a failed stage are removed only by the separate dest discard-leftover --declare-abandoned with the same execute and destructive gates. - The ADR scopes the sentinel rule to commands that inspect or change a prefix; dest identity and dest path-inventory take none. Add regression tests that failed before these changes (stale and foreign verify results recorded, unlock released after a rename whose record failed, another run's staging deleted) and record a second minimal Linux arm64 rerun with the fixed harness. Refs #23 * fix(ssh): bind harness results to a per-lock id and validate the intent Address the third review round of the #23 validation harness: - Every dest lock acquisition gets a random lockId. Every lock-bound result (activate, verify --run, receipt, unlock, rollback, receipt cleanup, retention), journal record and statement carries the prefix sentinel ID and that lockId, and op record refuses results of another run, another prefix or an earlier lock, including an earlier lock of the same run acquired at the same timestamp. callers_switched requires the publisher's unlock under the lock that published the receipt. - The activation intent's presence and validity are separate: a present intent that is not exactly this lock's closed record (false, 0, empty, null, array, malformed, extra or missing keys, another run, lock, target or staging, or not a regular file) refuses unlock, activation and receipts as activation_intent_unreadable and is never treated as absent. - Split the interrupted-activation test into a deterministic intent write failure before the rename and the persisted post-rename state; no crash between files is physically injected, and the docs say so. - Scope the ADR and VALIDATION wording: the full Linux arm64 cells L3-L8 are historical evidence of harness revision 210759a1 (cc7fe23); the final revision was rerun on that host only for the stated subset. Add regressions that failed before (an invalid intent let unlock release an unreceipted install; an earlier lock's receipt was recorded under a new lock of the same run) plus same-timestamp and another-prefix negatives. Refs #23 * fix(ssh): refuse replayed lock acquisitions and unrelated breaks in the journal Close two operator-journal freshness gaps in the #23 validation harness: - op record accepts a lock acquisition (prefix ID and lockId) only once per journal: re-recording it, whether replayed after it closed or repeated while current and from any run, is refused as acquisition_replayed and never deduplicated, so an earlier acquisition cannot become current again and revive its old unlock or receipt results. - An acquisition stays current until its own run's unlock of the same pair or a recorded break that closed exactly that pair. A break result closes it only when its prefix ID and broken lockId name an open acquisition recorded in this journal; unowned overrides, other prefixes' or journals' locks and already closed locks are kept as audit records that close nothing, and recording the same break twice is refused as break_replayed. Add regressions that failed before (a replayed earlier acquisition was accepted; a break on another prefix ended the current holder's lock) plus stale-break, duplicate-break and legitimate-recovery cases. The Linux host was not rerun for this journal-only change. Refs #23 * fix(ssh): treat a recorded lock break as a tombstone for its acquisition Close the out-of-order journal gap in the #23 validation harness: a break recorded before its acquisition (break first, acquisition result recorded later) no longer lets that acquisition become current. op record refuses a lock_acquired whose prefix ID and lockId already appear anywhere in the journal as an acquisition or as a recorded break's broken lockId (acquisition_replayed). A break naming the same lockId on another prefix is an unrelated generation and blocks nothing; existing recovery is unchanged. The ADR now limits "closes nothing" to overrides whose owner pair cannot be identified: a break of a lock with a readable owner whose exact pair is an open acquisition here does close it. Add a regression that failed before (a late-recorded acquisition was accepted after its break) plus the other-prefix case. Verified with the focused harness tests only. Refs #23 * docs(ssh): align the harness lock-break comment with the ADR The op record comment still listed an unowned override as always closing nothing. Limit it to overrides whose owner pair cannot be identified, matching the ADR: a break with a readable owner whose exact pair is an open acquisition recorded here does close it. Comment-only change; no code line changed. Refs #23 * fix(ssh): tighten harness leftover removal, operator-check order and recordable results Address three code-review findings on the #23 validation harness: - dest discard-leftover removes only a staging tree with no marker entry at all. Any marker entry, whether this workflow's, another manager's, unparsable, invalid, non-regular or symlinked, is refused as staging_has_marker and left byte-for-byte unchanged; --declare-abandoned and the execute/destructive gates are not a permission to delete what something else may own. - op record accepts an operator dry-run only after a doctor recorded since the latest verify of the same target under the same lock, and the operator-checks statement requires the recorded order verify, doctor, dry-run. A re-verify makes an earlier doctor stale. This is the order of journal records, not proof of when the operator commands ran. - dest receipt-cleanup and dest retire results are recordable as receipt_cleaned and retired, with the same executed-result, run, prefix and lock binding as other results; receipt_cleaned keeps mode, receipt state and ownership basis. Other event names stay usage errors. The ADR lists the recordable results. Add regressions that failed before (foreign and invalid markers deleted by discard-leftover; a dry-run recorded before any doctor; cleanup and retention results not recordable) plus reverse-order, stale-doctor, stale-lock, dry-run and other-run negatives. Verified with the focused harness tests only. Refs #23 * docs(ssh): clarify deployment journal event and audit scope Distinguish destination results from operator events and state that cleanup and retirement records are audit entries, without changing switch or statement eligibility. No executable code changes. Refs #23 * chore(release): prepare 0.5.0 platform qualification groundwork Carry forward the four exact skill profiles, preserve historical evidence and update current multilingual version examples. Linux observation, Windows observation/storage and Windows jump remain unsupported. Preparation only; no staging or publication. * docs(release): align API examples and retain immutable validation history Preserve historical evidence text, keep the supported handoff scope explicit, and pin previous-version SSH refusal plus plausible unreviewed skill profiles in focused fixtures. * fix(ssh): scope harness caller state by prefix and make receipt publication replayable Address seven inline review findings on the #23 validation harness: - Caller state is keyed by prefix and install name. callers_switched and callers_unswitched take an explicit --prefix-id that must be a prefix the journal has locked; switches no longer cancel across prefixes, and no-caller/receipt-owned statements and the receipt lookups are scoped to the current lock's prefix. - verify runs launcher and native probes only after every static check (real owned directory, consistent marker, manifest, staging gone) passes. - The explicit lock override removes only the known lock metadata entries, each a file, an unfollowed symlink or an empty directory; unknown entries and non-empty directories are refused before any removal. - dest receipt syncs a publication intent with the exact receipt bytes before writing the receipt. A retry after a lost response under the same lock and proof replays the committed receipt (bytes and verifiedAt unchanged) or completes a lost write with those bytes; changed, corrupt or orphan receipts, stale proofs, other targets and later locks fail closed, and op record accepts one receipt_published per target under a lock. - After run_ended only a run-ended statement is issued, even while the run's lock remains on disk. - callers_switched accepts a publishing acquisition closed by its run's unlock or by a recorded break that closed exactly that prefix and lockId; other-prefix breaks, stale breaks and unknown closures do not count. - path-inventory treats empty PATH components as the current directory and inventories ./session-peer there. Add regressions for each finding; they failed before (two of them, and two existing tests, only on the new --prefix-id argument) and pass after. Verified with the focused harness tests only. Refs #23 * fix(ssh): complete harness receipt recovery and validate publication intents Address the root review of the #23 harness publication path: - dest receipt --adopt-existing is an explicit, non-destructive recovery: after a run wrote a receipt, lost the response, ended and had its lock broken, a new run under a fresh lock with fresh verify, doctor and dry-run publishes the still-matching receipt under that lock. Receipt bytes, the original runId and verifiedAt are kept; receipts not matching the marker and manifest, invalid receipts and earlier-lock proofs are refused. - Completing a lost receipt write from a publication intent now requires every static check (and the probes when executed) and the current marker runId, identityHash and recomputed manifest to equal the committed receipt; a rolled-back or changed target is refused as publication_target_changed, and the result is rechecked after the write. Replays also recheck the install. - Publication intents must embed a receipt of the closed schema (exact keys, receiptVersion 1, 32-hex runId, 64-hex hashes, ISO verifiedAt); other valid JSON is refused before any write. - Lock metadata entries of other file types (FIFO, socket, device) are refused before removal. - Caller records without a prefix make the caller count unusable (caller_history_unusable) instead of counting as zero; older journal formats are not supported for caller decisions. - The test helper for a second prefix runs the operator CLI against that prefix's own wrapper. The ADR states statement issuance scope and the one-publication-per-lock versus one-record-per-target distinction. Regressions: the completion, schema, file-type and legacy-record tests failed on 839f2f6 and pass now; the adoption tests failed there on the new --adopt-existing flag. Verified with the focused harness tests only. Refs #23 * test(handoff): observe queue evidence without relying on file notifications Keep the 10-second readiness deadline and inspect the persisted synthetic queue record with bounded polling. Report complete child-close output when send exits before queue evidence. Add notification-suppression and early-refusal regressions. This hardens a reproduced fixture weakness; it does not establish the cause of earlier CI failures or retry a CLI submission. * fix(harness): share receipt validation across completion consumers Use one closed receipt schema and one static-check predicate for initial publication, replay and adoption. Reject activation after publication scope is committed so rollback cannot revive an old proof under the same acquisition. Add reuse, adoption, unlock, staging and reactivation regressions; full CLI execution remains required in CI. * test(release): derive successful deployment doctor fixture from package version Keep the explicit wrong-version refusal while allowing the intended wrong-target regression to reach its own guard after a release version change. * fix(ssh): track retained staging, sync receipt publication and harden manifests Address three review findings and one fixture issue on the #23 validation harness: - already_provisioned records the staging tree it keeps in the lock (retained.json, bound to run, lock and target). Until that tree is explicitly discarded, the final verify (stagingGone false, no probe), receipts and adoption depending on it, unlock and further activations are refused; a present but invalid record is refused, never treated as absent. - The manifest's file and link maps have no prototype, so a root entry named __proto__ (file or symlink) is recorded and later changes are detected before verify or receipt. - Receipt publication is synced before success: intent and lock directory, then the receipt file, .receipts and the root, then a publication.synced.json marker, for first writes, completed writes, replays and adoption (existing bytes are never rewritten). Unlock keeps the evidence and refuses while a receipt or its install exists without the marker. Journal records write every byte (short writes continue), are synced, and are truncated back on failure. Test-only environment hooks trace fsync order, inject one fsync failure or force short writes; they add failures only and do not qualify power-loss behavior. - The operator-doctor positive fixture uses the package version instead of a hard-coded 0.4.0; the wrong-version negative stays 0.3.9. Regressions for each failed before (retained staging released, a __proto__ change undetected, no sync guard or journal fault handling) and pass now. Verified with the focused harness tests only. Refs #23 * test(handoff): keep warm fixture WAL identities stable * docs(release): distinguish current source from historical platform trials * fix(ssh): resync existing publication metadata and report journal rollback honestly Close two bounded gaps in the #23 validation harness: - Every executed receipt write, completion, replay and adoption now syncs the existing publication intent and the lock directory before the receipt, .receipts and the root, and then writes or resyncs the synced marker and the lock directory before reporting success. A failed intent sync stops before the receipt sync; a failed marker sync happens after the receipt and its directories were synced and fails the step without implying the receipt is lost. - A failed journal append attempts a rollback (truncate to the previous length and sync). journal_append_failed with rollback restored is reported only when that is confirmed; otherwise journal_append_unknown with rollback unconfirmed keeps the original and rollback errors, and the operator must inspect the journal first. A failure never promises the record is absent and the append is never retried. Test-only hooks can now fail only the first N matching fsyncs and fail the truncate. The ADR also states that retained staging only blocks while it is pending; after the explicit discard the lock's statements remain usable. Journal regressions failed on 61f37f8 (harness_error) and pass now, run in a private directory under the external volume's tmp root. The replay sync-order test needs a dedicated prefix, which that root's ancestors correctly refuse; it is unrun locally and left to CI. Refs #23 * fix(ssh): sync pending intent before completing a missing receipt Preserve the publication ordering contract when an earlier intent write failed its sync. Require the intent and lock directory sync before creating the missing receipt. Add a regression for repeated intent-sync failure; full CLI execution remains a current-head CI gate. Read-only paired Claude/Codex review found no mandatory defect. Refs #23 * test(handoff): observe persisted initialize readiness and early exits * test(handoff): stabilize synthetic observation and readiness fixtures Backport the independently reviewed release-preparation test corrections: persisted queue and initialize readiness with unchanged deadlines, early-close diagnostics, and a retained synthetic warm WAL connection. Include the discriminating notification and keeper regressions. Runtime guards, delivery assertions and platform support are unchanged; the original CI causes remain unproven. Refs #23 * fix(ssh): bind remote-bin, links, journal writers and caller state in the harness Address six review findings on the #23 validation harness: - The attested --remote-bin must be an absolute POSIX path that, after lexical normalization (never resolved remotely), equals exactly the wrapper path reported by the verified destination result (a new harness-only verify field); detours, other wrappers and other prefixes are refused. It remains operator attestation. - Manifest links must resolve inside the install, also through chains; absolute, escaping, dangling or looping links are refused as unsafe_link during staging before anything reads through the tree, and before every probe. Bounded internal links stay allowed. - Executed op begin and op record hold an exclusive <journal>.lock (mkdir) across read, validation, append and rollback; contention is refused as journal_busy without waiting, stealing or killing, and dry runs and op statement refuse while it is held without writing. A lock left by a crash is removed by the operator after checking. No claim covers hostile same-user writers or power loss. - callers_switched and callers_unswitched are refused while any recorded acquisition on the prefix is open (acquisition_open), so a statement issued under an open lock stays true. - A publication is superseded by a later rollback, retirement, receipt cleanup or new activation of the same prefix and name (publication_superseded); a newer completed publication is required. The ADR replaces the earlier audit-only description. - npm receives tarballs as absolute paths of regular files, so none can be read as an npm option; the hashed path is the one npm receives. Journal-only regressions (journal lock contention and rollback isolation, caller fences and remote-bin binding on shaped destination results) failed on e9f99e0 and pass now in a private directory under the external volume's tmp root. Dedicated-prefix fixtures (manifest links, npm argv, CLI caller and supersede flows) are unrun locally and left to CI. Refs #23 * fix(ssh): require the canonical wrapper path and lock journal reads in the harness Apply root's design refinements to the six E9 fixes: - The attested --remote-bin must already be a canonical absolute POSIX path (no ., .., repeated or trailing /) equal to the verified wrapper; a path that only normalizes to it is refused, because a shell resolves link/.. through the link. Nothing is resolved locally or remotely. - op statement and journal dry runs now hold the ephemeral journal lock across their read, so a statement never snapshots a line that a concurrent failed append later rolls back. The ADR states the lock directory as their only effect, that a crash can leave it, and that it is removed by the operator; no stale takeover. - The ADR records that absolute links are always refused (they go stale or outside after the activation rename) while relative internal links survive it with referents covered, and that activated records without an outcome from earlier revisions fence as new activations. Tests: the shaped remote-bin case now requires the exact wrapper (it fails on 8c6f224's normalizing check), the rollback-isolation test also checks that a statement is refused during a held append, and the internal-link fixture checks that the link survives activation and that referent changes are detected. Refs #23 * test(ssh): pin the journal rollback window and the retire unswitch order Add a test-only pause point after a failed journal append and before its rollback. A deterministic regression holds a complete appended lock_acquired line on disk while its rollback waits: a statement and a second record are refused as journal_busy, and after the confirmed rollback no statement can be issued from that acquisition (lock_not_recorded). The retire test notes that releasing, unswitching and locking again is the same as unswitching before the lock, with the guard unchanged. No production behavior changes. Refs #23 * fix(ssh): follow link chains, tarball paths and journal identity as the OS does Address five review findings on the #23 validation harness: - Manifest links are followed one component and one link at a time as the OS would; every intermediate location must stay inside the install, so a hop out through another location or a .. above the install root is refused even when the chain comes back. Absolute, dangling and looping links stay refused, and nothing is probed before the check. Relative internal links survive the activation rename and their referents stay covered. - Tarball paths are interpreted by the OS (lstat and realpath of the given path), never lexically, so a symlinked ancestor followed by .. selects the file the OS reads; the final component must be a regular file and npm gets its absolute real path. - A journal must have exactly one link (journal_aliased), and the open file is checked to be that same single-link file, unchanged since the read, before an append and before its rollback. - A cleanup, retirement or rollback recorded since an acquisition closes its publication: a later receipt result under the same lock is refused (publication_closed); recovery needs a new lock and checks or the explicit adoption. - op init holds the journal lock from the exclusive create until the header line and newline are written and synced; its dry run holds it only to check for an existing journal. The harness can now be imported by its tests (pure helpers exported; the command runs only when executed), and the test file accepts a test-only DEPLOYMENT_HARNESS_SCRIPT to compare against another revision's copy without replacing the worktree file. Refs #23 * fix(ssh): preserve native paths and reject incomplete journal records Use native realpath for the raw tarball path so symlink ancestors followed by .. select the OS file. Require directories for every remaining link component, including a trailing slash or dot. Refuse a journal lacking its final LF before any append, without repair or migration. Add discriminating filesystem and journal regressions and align init coordination comments. Two focused regressions, syntax, types and repository checks passed locally; dedicated-prefix stage fixtures remain a current-head CI gate. Fresh paired read-only Claude and Codex supplemental review found no mandatory issue. Refs #23 * chore(release): defer deployment harness and narrow 0.5.0 scope Exclude the #155 harness, its dedicated fixtures and new deployment qualification claims. Restore the existing main-branch ADR and retain independently reviewed handoff fixture readiness fixes. Preserve all preparation history; #23 remains open and minimum-contract redesign is tracked separately. Refs #158 * docs(release): remove the deferred harness from 0.5.0 procedure Align the release procedure with the user-approved scope: #153, #156 and #154 only; defer #155 to checklist-first contract redesign #158.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Refs #130. Preparation PR. Native profile selection becomes platform-aware (exact tuple table), the Linux procfs machinery is implemented and tested, and a linux-arm64 / Codex 0.162.1 candidate is recorded with real artifact, schema and injection evidence, but it is not activated. Every Linux tuple remains unsupported (locally and over SSH) until the frozen follow-up design below is implemented and reviewed.
What is implemented
src/native-profiles.ts: frozen, validated exact(platform-arch, version, commit, platformOs, storageBinding, ownerInspection, sshDestination, artifact)rows; no SemVer range, libc/arch alias or cross-platform inheritance; new rows must pin the executable SHA-256/target; Linux rows can never be selected by SSH destination requests. Selectable rows: darwin-arm64 0.160.1/0.162.1 (unchanged).CANDIDATE_PROFILESholds the non-selectable linux-arm64 0.162.1 entry.app-server.ts: exact(version, platform)queue capability and schema evidence (linux-arm64 0.162.1 schema hashes recorded as evidence only);initialize.platformOsmatches the row; pinned artifact digest and Linux procfs binding run in an owned worker; at the original remaining budget the supervisor requests group termination and the caller refuses, while actual reaping of a worker blocked in kernel I/O may occur later. Caller-siderealpath/stat/lstatstay synchronous with deadline checks only, as on Darwin./proc/<pid>storage binding (direct child, own group, all UIDs, exe inode, stable start time, exact canonical paths, deleted descriptors refused; shims refused); writer probe--procfs-owner(/proc/lockssole exclusive flock holder = lsof owner, stable start time/UIDs) without changing the generation.metadata-observation.ts/handoff-operations.ts: exact(version, platform)qualification and retained resume; foreign-platform retained records terminateunsupportedbefore any probe. Fix: the structural capability check no longer becomes ambiguous when one version has rows on two platforms (found by the live run as a pre-effect refusal; regression test).cli.ts(one token): destination wire requests passremoteso SSH requests cannot select Linux rows.Recorded Linux arm64 evidence (candidate, not activated)
071cbe8d…cabe5equals the executable extracted from upstreamrust-v0.162.1codex-aarch64-unknown-linux-musl(.tar.gzbf3ca271…,.zst).handoff statusand an independent wait succeeded; ACK not requested; 2 model turns total. Fixture:test/fixtures/linux-observation-native-evidence.json(identifiers omitted). Whether the Darwin dedicated threads had a prior turn is not recorded.Why the candidate is not activated (review round 2)
ps lstart, so a different-version or gnu writer beside a pinned musl queue binary is not distinguished.ps lstartat 1-second resolution).Closing (2) safely needs an optional private ledger field, so the design is frozen in PARITY.md ("Linux row activation follow-up design": writer
/proc/<pid>/exebinding; optionalobservationOwnerfield with start time/boot ID/exe identity; fail-closed for missing/old records; an end-to-end CLI check for a missing destinationremoteflag; procfs lock/device matching verified only on ext4; negative test list) instead of pushing an unreviewed schema change.What remains unqualified
All Linux observation cells (including the recorded candidate), SSH-remote observation, Windows (#131), automatic receipt/ACK (#132). External review inputs received summaries of the native send/status/wait JSON and generation values, not raw records; the root review audited the raw records separately.
Validation checkpoints
dd21302805ae215273ae7c5e59ef514c47e8eb68source checkpoint: macOS arm64 / Node 24.16.0 / pinned Python reference 8ca77cf,npm test: 408 total / 400 pass / 0 fail / 8 skip; Linux arm64 / Node 24.18.0: 404 total / 376 pass / 0 fail / 28 skip. The Linux run used fixtures only, without credentials, a model turn or an installation change. These are executor-recorded results; the raw Linux log does not contain a HEAD marker. It is associated with the checkpoint by the executor's run record, rather than an embedded commit attestation.ffe8afc75538a8283df4eb3e2dae9a65d8125002and current head104e3dcb0296ab6b11a7733a2a4b6be480e09f68:npm run build,npm run test:types, repository and diff checks passed; focused checks: 80 pass / 0 fail / 3 skip at each. These heads change documentation, comments and an evidence-description string; no runtime code statement changed. No new full-suite, Linux-host or live-model run was performed at these heads.npm run test:packageat the exactffe8afc75538a8283df4eb3e2dae9a65d8125002source export: PASS (isolated install/uninstall and package allowlist).node scripts/release.mjs packinitially stopped because a Git archive has no Git metadata; after supplying the helper's supportedGITHUB_SHAequal to that exported commit, pack and artifact checks passed. The initial failure and corrected run are retained. No publication command ran. The two source files changed by104e3dchave identical comment-stripped compiler output toffe8afc; these checks are not claimed as new full-suite or packaging runs at104e3dc.2f3b35d(the candidate was selectable) the Linux SSH regression failed with the wire flag removed and passed with it; atb804115the two-platform capability regression failed before its fix and passed after. Those are checkpoint-specific observations. The current candidate remains disabled, and activation requires a discriminating end-to-end remote-flag test.Out of scope
Ledger schema changes, version bump/release, Python/skill pins, relay/device (#29-32), SideSession/Steer, automatic receipt, MCP and wake. PR #82/#142 are excluded.