Repository navigation
Conversation
bin/build-release.sh builds a release archive from uv.lock (pinned wheels, hash-checked) plus the flow wheel, a checksum and an openssl signature. bin/test-offline-install.sh builds two signed releases, then as root inside run-egress-blocked.sh installs the first from its wheelhouse, refuses a tampered second, updates to the signed second, rolls back and runs the air-gap attestation. The new flow-onprem-offline job runs it, and runs bin/test-update.sh, which no job ran before.
…kout The version check ran python -c from packages/flow, so it imported the source checkout and reported 2.6.0 after the update to 2.6.0.post1. Run it isolated from /, require the module to live in the venv, and compare the module with the installed distribution and the CLI's --version.
A writer that found the audit lock owned by an exited process removed it without re-checking. If the owner released between the read and the removal and another writer took the lock, the breaker deleted the live lock and two writers could chain to the same parent. Break stale locks only under a second lock and only if the lock still names the same dead owner. Add a deterministic test that forces the handover, and print the verifier output when the concurrent-writer check fails.
…, and test it in CI The Dockerfile installed from an unpinned ./wheels directory that nothing produced, and its command (bin/run-queue.sh relative to the storage volume) could not resolve. build-image.sh now verifies a signed release archive against the pinned vendor key, extracts it, and builds with --network none from the release's lock-pinned wheels. docker-compose.yml runs a named, never-pulled image with an absolute command. test-container.sh builds it in CI, refuses a tampered archive, shows a missing wheel fails the build, and runs the runner on the compose network with no route out.
…r(1) Ubuntu 26.04 ships uutils mkdir, which reports success to both callers when two processes race to create one directory. The audit-log writer lock and the release update lock both treated a zero exit from mkdir as ownership, so on that image concurrent audit writers chained to the same parent (the "concurrent audit writers preserve one hash chain" CI failure) and a second update could proceed beside a live one. Ownership is now the shell's own noclobber create of the pid file inside the lock directory (O_CREAT|O_EXCL), and the stale-lock breaker lock is an exclusive file too. Tests model the uutils behavior with a mkdir shim that never reports EEXIST; on the previous code they fail.
…ad the root-owned audit log from inside the image
Independent adversarial review: BLOCKP2: Keep unrelated local files out of the image. build-image.sh:69–70 copies the deployment directory with a short exclusion list; Dockerfile:38 then embeds everything copied. With an unchanged signed archive, adding an owned synthetic P2: Refuse a missing base before invoking the builder. build-image.sh:73–76 does not enforce the documented local-base requirement. With an absent Validation on WSL / Docker 29.9.3: the exact shipped container suite passed 18/18, including real engine/privacy imports, malformed-job audit, and Compose egress controls. The 43 Flow + 46 root contract tests passed on head |
…plicate dialog) (#1615) * identity: read the band of a target inside a dialog on the dialog alone (#1347) The recorder stores the box of the topmost dialog holding a clicked target (PlaywrightBackend.dialog_region_at). The compiler reads that step's identity band on the frame blanked outside the box and stores Anchor.dialog_region. Replay blanks the live frame outside the live dialog the same way, and fails the identity check closed when no dialog holds the resolved point. Also: the throughput harness retries its form setup once after a navigation race destroys the evaluate context (#1348). * identity: address the dialog-scope review Scope to modal dialogs only (dialog:modal, aria-modal, alertdialog, a shown Bootstrap modal) and treat an opacity-0 dialog as gone. Require the box to hold the probed point. Mask the extra identity looks' fresh frames with the same dialog box; give the signal quorum the whole frame. Heal re-reads a dialog target's band on the dialog and moves dialog_region with the point. The render-scaled view maps the probe. The harness retry tolerates a frame that detaches while it waits. * identity: a dialog target's band is the whole dialog The row of a dialog button often holds nothing but the other buttons, so on OpenEMR's duplicate dialog the scoped row band was too short to arm identity and clinical-write would refuse the save. Read every line of the dialog instead (its result text and count included), at compile and replay, with no row re-read, and skip the row census for a dialog target. * throughput harness: --backend, to replay with the backend the bundle was recorded with A bundle the demo's record command makes carries the OpenEMR adapter's form field identity; replayed through the base Playwright backend, its first step reads only the field label and halts. * benchmark: identity at OpenEMR's duplicate dialog, before and after #1347 On the OCR band path the main bundle refused the confirm step at 8 of 8 form scroll positions behind the dialog; the dialog-scoped bundle verified at all 8 and still refused a dialog that lists a possible duplicate. 26-item worklists: 26/26 correct on both. * Register the dialog identity measurement and add its capability row * fix: preserve dialog row identity (untested WIP) Signed-off-by: abrichr <[email protected]> * test: pin dialog row and mask refusal regressions Signed-off-by: abrichr <[email protected]> * fix: keep dialog identity checks generic and typed Signed-off-by: abrichr <[email protected]> * test: separate modal row text from button crops Signed-off-by: abrichr <[email protected]> * fix: publish repair hold metadata atomically Signed-off-by: abrichr <[email protected]> --------- Signed-off-by: abrichr <[email protected]>
Signed-off-by: abrichr <[email protected]>
* chore(release): prepare openadapt 1.20.0 on Flow 2.6 Signed-off-by: abrichr <[email protected]> * chore: refresh published platform components for launcher draft Signed-off-by: abrichr <[email protected]> * chore: synchronize launcher candidate lock version Signed-off-by: abrichr <[email protected]> * chore(release): lock launcher against published Flow 2.6.0 Signed-off-by: abrichr <[email protected]> --------- Signed-off-by: abrichr <[email protected]>
* feat: collect explicit benchmark timing observations Signed-off-by: abrichr <[email protected]> * fix: narrow optional timing values before comparison Signed-off-by: abrichr <[email protected]> * test: preserve timing coverage and outer phase diagnostics Signed-off-by: abrichr <[email protected]> * fix: bind untimed observation fields by name Signed-off-by: abrichr <[email protected]> * ci: check the generic benchmark timing contract Signed-off-by: abrichr <[email protected]> * fix: retain missing named phase coverage explicitly Signed-off-by: abrichr <[email protected]> --------- Signed-off-by: abrichr <[email protected]>
Signed-off-by: abrichr <[email protected]>
…script-sent saves (#1851) * flow: API steps for multipart saves, the clicked button's value, and script-sent saves * flow: types and formatting for the new API step shapes * benchmark: API-step generalization harness for five apps (Redmine, WordPress, NetBox, Dolibarr, Trac) * flow: real-app test of the new API step shapes on the lab fixtures (opt-in) * llms-full: refresh for the API-step capabilities * fix: bind API form shapes to native submission evidence Signed-off-by: abrichr <[email protected]> * fix: preserve refusal wording and settle synthetic form capture Signed-off-by: abrichr <[email protected]> * fix: compare form destination with transport URL construction Signed-off-by: abrichr <[email protected]> * benchmark: generate the NetBox fixture's superuser token per run; pin the old synthetic literal's exact gitleaks finding --------- Signed-off-by: abrichr <[email protected]>
Signed-off-by: abrichr <[email protected]>
* No command falls back to the demo app on its own replay with no --url (and no backend.url) served the bundled MockMed app; it now needs --demo-app for that, and refuses otherwise. --drift needs --demo-app. The launcher help, quickstart docs, the quickstart lifecycle script, e2e tests and Desktop's frozen smoke test pass it. The variant router's first-screen probe returns nothing without a URL. qualify accept's break-it gate ran every workflow's proposed oracle against MockMed (its banner text, /api/encounter, /api/db). It now builds the lie from the workflow: an in-process store that did not change, and a screen that shows the workflow's own success text, every typed value, and whatever a screen read looks for. The reference Execute worker ran the MockMed tutorial driver against any admission's target_url (resetting and reading it as MockMed). It now refuses such an admission before anything runs. * Review fixes: --demo-app tests, attached-browser refusal, synthetic targets Adversarial review of the fallback change: two tests replayed without a target (now --demo-app); --demo-app with an attached browser was silently ignored (now refused); a synthetic Execute admission that names a target_url was reported as verified without running (now refused before anything runs); the bug template shows --demo-app. * Frozen smoke test passes --demo-app only to a Flow that has it; format Desktop's frozen engine pins a released Flow, which serves the demo app whenever no URL is given and doesn't know --demo-app. * Re-run CI * Lower the engine generality baseline: no command names the demo app now --------- Signed-off-by: abrichr <[email protected]>
…al systems of record (#1937) * feat(policy): add record-write, a general write policy for non-clinical systems of record * release: register record-write.yaml in the public artifact inventory check_release_consistency.py refused the tree: the new policy file was not in public-artifacts.json.
…age that is not loaded
|
Answering BLOCK 6648883346 at 62c4849. P2, unrelated local files: build-image.sh no longer copies the deploy directory with an exclusion list. It copies a named list into the build context: Dockerfile, docker-compose.yml, onprem.example.yaml, README.md, COMPLIANCE.md, UPDATE.md, and the four scripts the image runs (run-queue.sh, audit-log.sh, verify-airgap.sh, run-egress-blocked.sh). The scripts keep their modes. A named file that is missing, or is a symlink, stops the build. Host-only installers, units and build or test scripts stay out too. P2, network base resolution: before test-container.sh now:
Testing, and what wasn't tested: Docker isn't available to me (the Mac's daemon isn't running, and I couldn't install it on my Linux box), so I haven't run the new test-container.sh checks against real Docker. Since this PR targets agent/142-c, the flow-onprem-offline job doesn't run on it either. Instead I ran build-image.sh against a recording docker shim, with a signed placeholder release and a site copy holding those stray files:
shellcheck finds no warnings. test-update.sh passes 49, and test_onprem_reboot.py plus test_onprem_service.py pass 41. GitHub reports this PR as conflicting with agent/142-c in .github/workflows/packages.yml. That conflict was already there, and this commit doesn't touch that file. I left it alone. |
…e version authors (#1854 a+b) (#1873) * ensure_record: bind the read-back to the last version written, and name each version's author (#1854) * ensure_record: keep the version_trail docstring app-neutral for the engine generality check * fix(flow): order ensure-record versions by instant, not timestamp text (#1925) * fix(flow): order ensure-record versions by instant, not timestamp text version_trail sorted versions by when.isoformat(), which keeps each timestamp's own offset, so versions written with mixed offsets came out in the wrong order and the audit trail's n-th write named the wrong version's author. bookkeeping_only sorted its chain by the raw lastUpdated text the same way; with a later version's time out of place, a bookkeeping stamp ten minutes from its own version's time was checked against the later version and excused. Both now sort by the parsed instant. In bookkeeping_only a version time that cannot be read (unparseable or with no time zone) now refuses the bookkeeping excuse instead of being sorted as text. * fix(flow): name version authors from the audit order only when it is unambiguous * fix(flow): refuse bookkeeping when two versions share an instant Versions with the same lastUpdated instant have no known order, and the server's return order is not a chronology. bookkeeping_only now refuses the excuse instead of keeping response order for ties, so a newest-first history can no longer hide a final stamp change. * fix(flow): narrow version instants to datetime for the sort key
Signed-off-by: abrichr <[email protected]>
…h trial (#1936) * fix(qualify): let verifier.session renew FHIR and GraphQL read-back credentials * fix(qualify): refuse a session hook that opens no client
|
From: Grok, To: coordinator Merged origin/main at bc5357a (conflict-free locally after deepening the shallow main fetch). onprem_service+reboot: 41 passed. |
Part of the on-prem deployment work. Stacked on #1918 (base
agent/142-c2), which addsbin/build-release.shand theflow-onprem-offlineCI job.What this does
The container option in
deploy/on-premdidn't work as shipped. The Dockerfile installedopenadapt-flow[privacy]from a./wheelsdirectory that nothing produced and that wasn't pinned to the lock. Its command,deploy/on-prem/bin/run-queue.sh(andbin/run-queue.shin docker-compose.yml), was a relative path resolved from the storage volume, so the runner could not start. Nothing built or ran the image.bin/build-image.shbuilds the image from a signed release archive (the onebuild-release.shmakes). It checks the signature against the pinned vendor key with the same code asinstall.sh --update, refuses a bad archive before calling docker, extracts the archive with the bounded extractor, and runsdocker build --network none. pip only sees the release's own lock-pinned wheels, so a missing wheel fails the build instead of reaching an index. It tagsopenadapt-flow-onprem:<version>and candocker saveit.pip check. It uses an absolute command path. The base image defaults topython:3.12-slimpinned by digest and must already be loaded on the host.OPENADAPT_FLOW_IMAGE(required, no default) withpull_policy: neverand the absolute run-queue path. The internal network and the no-ports rule are unchanged.bin/test-container.shruns in theflow-onprem-offlinejob, after the releases are staged and before the egress-blocked install. It checks that:Testing
dockerthat records its arguments and the build context:release/(VERSION, requirements.lock.txt, 89 wheels) andon-prem/, and calleddocker build --network none --pull=false.docker build -q, pip's error never reached the log, so the missing-wheel build failed for the right reason but the test couldn't tell; it now uses--progress=plain. The runner is root in the image and audit-log.sh makes the audit directory 0700, so the host could not read the log; the test now reads it from inside the image.Not tested