Document Allocation Arrange amendment and publish bounded planner evidence
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
# Explicit Allocation Arrange amendment — 2026-09-23
|
||||
|
||||
**Status: accepted design; pure planner verified, App integration and native acceptance pending.** Codex-9e8r6t /root adopts this bounded policy after reviewing the actual OA/SA experiment, its independent critique and corrected geometry oracles. No user-owned application specification is changed.
|
||||
|
||||
User-derived basis: [PROJECT_GOAL](../PROJECT_GOAL.md), [multiselect contract](multiselect-contract-20260923.md). Existing authority: [Allocation drag v2](release-activity-allocation-drag-contract-v2-20260911.md) and its linked destination-feedback amendment. [Experiment and planner evidence](allocation-arrange-planner-20260923.md) records the decision history, exact source, results and limits.
|
||||
|
||||
## Scope of the change
|
||||
|
||||
Explicit **Arrange only** supports one or more selected work/performer placements through one declared footprint and one combined geometry check. A distributed work root does not fail Arrange solely because its allocation summary is MixedOrUnresolved or its semantic descendants occupy different visual performer groups. Its affected projected footprint must still translate rigidly and satisfy all geometry/readability checks below.
|
||||
|
||||
This narrowly supersedes v2's mixed-composite/coherence pre-veto **only for explicit Arrange**. Ordinary work-body assignment is unchanged: work-only groups use one frozen common destination, normalize work ancestry, and admit each root under existing role/coherence rules. A mixed/distributed composite still refuses ordinary assignment; different valid initial performers on independent roots do not alone require refusal. Same-effective-performer role-only roots gain no direct Allocation, unsupported role exits refuse wholly, and no drag changes semantic work ownership. Ordinary mixed work/performer selection cannot partially assign its eligible members. Offer Arrange only when its own full-set admission is available.
|
||||
|
||||
Arrange admission cannot depend on having two selected items. C alone and {A,C} use the same rule; adding A changes the actual movement footprint rather than unlocking an otherwise identical operation. Existing ordinary performer arrangement remains governed by its existing behavior; this amendment defines the explicit mode consistently across cardinalities.
|
||||
|
||||
## Exact target and footprint definitions
|
||||
|
||||
1. Validate every original typed target before normalization: exact placement/lifetime in the same active Allocation diagram and layer, currently visible, eligible work or performer kind, and core-valid accepted Project. Any stale, missing, foreign, port, edge or grouping-relation member refuses the whole action. Same-element duplicate placement in one diagram is malformed input. Preserve exact selected membership and primary separately from planning roots.
|
||||
2. Normalize explicitly selected work roots by same-kind semantic ancestry. For each root, S contains its recursive same-kind work closure. Q is all existing active-diagram placements of the union S, including folded descendants. Unplaced work contributes no fabricated placement.
|
||||
3. V contains each explicitly selected performer placement and its accepted visual descendants, including folded descendants. R = Q ∪ V. Capture this union once; do not acquire semantic ancestors/siblings or new semantic roots merely because a work placement is an incidental visual descendant. Each R placement moves once. Authored placements outside R and every other diagram remain exact.
|
||||
4. The press anchor must be an exact selected placement. Snap its requested position once on the existing ten-world-unit grid and apply that one delta to all R. Another selected anchor may change the snapped delta but never the mode or R. Preserve authored sizes, fold states and port anchors. Arrange authorizes no destination unfold, reparenting, packing, Fit or automatic topology change.
|
||||
5. Preserve every engineering record, including Allocations, RoleAssignments, RoleRealizations and semantic parents. Resolve routes using accepted actual endpoint owners and the complete R delta map: internal pins with both owners moving by the same nonzero delta translate once; one-ended pins remain fixed. Relative labels and attachments remain exact.
|
||||
|
||||
## Combined geometry and its deliberate diagnostic boundary
|
||||
|
||||
Project the complete accepted and candidate diagrams using the appropriate semantic index. Check the entire resulting visible scene, not only moved cards. An unselected performer enclosure may change its derived bounds even though its authored record is untouched. Such growth is allowed only if the complete candidate meets model bounds and the existing unrelated-overlap rule: no new or enlarged positive-area overlap beyond the current 0.01 area tolerance; visual ancestor/descendant containment is exempt.
|
||||
|
||||
Also compare accepted/candidate diagnostic scenes. In each scene, temporarily unfold R and the visual ancestors necessary to reveal R; use the corresponding accepted/candidate visual ancestry. Include stationary geometry revealed by that required expansion. These temporary Diagram changes are never committed. A moved hidden child cannot evade collision checking through a selected performer's fold.
|
||||
|
||||
**Unrelated stationary folded interiors are outside this diagnostic domain.** Do not unfold every container in the diagram. Their visible collapsed headers still participate in the ordinary scene check. This limit prevents invisible distant contents from becoming an unexplained blocker; it does not promise that future expansion will be free of overlap. A stricter all-unfolded policy is a different candidate, not an implicit interpretation of this amendment.
|
||||
|
||||
Every R node's affected diagnostic footprint must preserve size and translate by the common delta. No automatic convergence/reflow is licensed by removing the semantic pre-veto. Check the required originally selected headers for visibility and containment in the captured viewport; a normalized-away selected descendant cannot silently disappear. Any unsupported footprint, unreadable selection, invalid bounds or new/enlarged unrelated overlap refuses the complete action. Show the actual combined candidate and affected counts; do not present independently valid singleton ghosts as evidence of group feasibility.
|
||||
|
||||
## Valid and refused examples
|
||||
|
||||
| Example | Required result under this amendment |
|
||||
| --- | --- |
|
||||
| Composite C contains x on A and y on B; select C; enough room for one rigid delta | Arrange may move Q={C,x,y}, preserving A/B authored positions and every allocation. Their derived enclosures may grow if the complete scenes remain admissible. Ordinary assignment still refuses the distributed root. |
|
||||
| Same model, select {A,C} | R additionally includes A and its accepted visual descendants. Move each union member once. The operation is not equivalent to C alone. |
|
||||
| Select parent C and its already covered child x | Validate both selected targets, deduplicate planning scope, move each placement once, retain the two exact selection identities/primary. |
|
||||
| X's translated bounds enter Y's old bounds, while both selected roots move clear together | Check simultaneous candidate geometry. Do not refuse because an independent singleton-X check treated Y as stationary. |
|
||||
| Unselected B's projected enclosure grows into stationary Z although no R card intersects Z | Refuse. Unchanged authored B geometry is not evidence that its derived enclosure is harmless. |
|
||||
| Folded selected A hides moved x, which newly intersects a stationary visible obstacle | Required diagnostic expansion detects the collision and refuses. |
|
||||
| Unrelated folded D hides Z that intersects moved x only in an all-unfolded alternative | Z alone does not block under this diagnostic policy. Required visible/R-plus-ancestor checks must still pass; retain D/Z authored records and D's fold. Future expansion may reveal overlap. |
|
||||
| Selection includes a work card plus port, edge or grouping-relation target | Whole-set refusal; no eligible-subset fallback. |
|
||||
| Snapped zero delta, unchanged semantics/folds/routes | No command and no history entry. Arrange never changes assignment merely because a pointer crosses a performer. |
|
||||
|
||||
## Lifecycle, source and history
|
||||
|
||||
Retain v2's clean-owner, dirty-pointer shielding, modal/tool priority and frozen camera/input lifetime. ArrangeNext is explicit and consumed once at press, whether the anchor is work or performer. Preserve the selected set and primary on selected-member press while distinguishing stationary release from group drag; a drag cannot become a singleton click after crossing the three-screen-pixel threshold and returning near its origin. Mode and footprint cannot change midway through a token.
|
||||
|
||||
Capture exact selection generation with document/revision, active diagram/layer, epoch, bounds/pan/zoom and accepted scope. Dirty source/property/behavior input, owner/tool/lifetime change, Fit/resize, Escape, focus loss or outside/hidden release cancels without partial movement. Retiring a token is irreversible even when numeric values later return. Unsupported mixtures never fall through to legacy MoveNode, assignment, reconnection or deletion.
|
||||
|
||||
Preview is immutable. On release, revalidate the same capability/snapshot, recompute combined geometry and compare the complete prepared Project with an independently constructed expected Project containing only the permitted R/route edits. Execute one Batch through normal Document source admission. Source failure/refusal leaves accepted source, selection/primary and history unchanged; successful movement is one Undo/Redo step with exact source roundtrip. Geometry detector assertions alone do not establish any of these transaction/lifecycle properties.
|
||||
|
||||
## Choice rationale and rejected alternatives
|
||||
|
||||
Retaining strict v2 is the smallest implementation but rejects a semantics-preserving explicit layout solely for distribution; until this amendment is implemented, its refusal remains truthful. Visual-selected-only translation is rejected because it omits required semantic/folded descendants. Sequential singleton planning is rejected because geometry, routes, deduplication and final expected Projects are not compositional. Universal unfolding is deliberately not chosen for this bounded mode; it introduces invisible unrelated geometry into admission. Packing/reflow and arbitrary convergence remain separate layout work.
|
||||
|
||||
## Evidence and acceptance still required
|
||||
|
||||
The [experiment/planner report](allocation-arrange-planner-20260923.md) is authoritative for exact runs, source identities, independent review and retained failures. It distinguishes actual projection/source/history evidence from policy predictions and App acceptance. Its independent expected geometry accounts for SA function ports; collision detection is not presented as atomic UI refusal.
|
||||
|
||||
Production integration still requires:
|
||||
|
||||
- Whole original typed-set admission, token/selection-generation, dirty/stale/source-failure, one-shot mode, irreversible threshold, cancellation and minimum-readable-text-scale checks.
|
||||
- OA/SA native workflows anchored on performer and work members, truthful counts/preview/refusal, one Undo/Redo, Save/reopen and exact unrelated-record preservation.
|
||||
- Separate ordinary work-only group assignment with per-root responsibility rules and one combined candidate/geometry gate.
|
||||
|
||||
This amendment defines a bounded Arrange capability. It does not establish all Allocation group interactions, general convergence, grouping removal, routing usability or completion of the multiselect issue.
|
||||
@@ -0,0 +1 @@
|
||||
** -text whitespace=cr-at-eol
|
||||
@@ -0,0 +1,24 @@
|
||||
# Allocation captured-gate evidence tools
|
||||
|
||||
Adapted from the reviewed Process prepare/verify/selfcheck tools. Read-only preparation consumes explicitly selected **closed** runs in CHECKOUT/.local/allocation-group-gates. No Cargo, source execution, checkout, GUI, network or archived helper execution occurs.
|
||||
|
||||
```powershell
|
||||
python -B prepare.py --root CHECKOUT --runs experiment-1 experiment-2 experiment-3 planner-document-1 probe-lint-1 format-1 --check-only
|
||||
```
|
||||
|
||||
Keep failed experiment-2: verification preserves its recorded compile failure rather than converting archive consistency into test success. The example selects the first six closed gates. Later closed planner runs can be explicitly listed with the same interface; the final package manifest is authoritative for its exact inventory. No implicit discovery includes active directories.
|
||||
|
||||
To create a portable package, replace --check-only with `--output NEW_DIRECTORY`. Existing output refuses. The exact seven raw files are required, with only `source-proof.json` accepted as an optional eighth file. No raw byte normalization or receipt rewriting occurs. Maps and nested input ZIPs deduplicate by SHA-256; other logical raw files keep their names. All original helper bytes, failed-run streams and optional proof bytes remain archived. The Allocation-specific manifest kind distinguishes this extension from the seven-file Process schema.
|
||||
|
||||
The gate.py and source-proof.py helper catalog is preserved. Every gate's recorded helper must match available bytes; use repeatable `--helper PATH` for older captures. If a proof exists, its exact comparator bytes must be available at the default `.local/process-source-evidence-tools/verify.py` or a repeatable `--comparator PATH`. They are archived under their content hash and never executed.
|
||||
|
||||
An optional source proof is independently pinned in the manifest with its full named commit. Verification binds it to the enclosing run, exact result receipt, captured map/count, completed gate time, status and comparator bytes/hash. Captured HEAD is preserved as historical metadata and is not substituted for the named source commit. This packager checks historical proof consistency; it does **not** repeat Git blob comparison. A source proof on a failed gate is source-identity evidence only, never a passing-test claim.
|
||||
|
||||
```powershell
|
||||
python -B PACKAGE/verify.py
|
||||
python -B selfcheck.py --root CHECKOUT --runs experiment-1 experiment-2 experiment-3 planner-document-1 probe-lint-1 format-1 --output TOOLS/NEW_SELFCHECK_DIRECTORY
|
||||
```
|
||||
|
||||
The verifier checks pins, exact ZIP inventory, process/start/result relationships, streams, command/exit identities, source capsules, vendor inventory and Cargo artifact relationships. Selfchecks compare packaged raw bytes to originals, reject existing output, and mutate only in-memory copies to test stream/helper/exit/capsule/proof corruption. The package contains tools, manifest, files.json and evidence.zip; selfcheck is a preparation utility, not packaged runtime input.
|
||||
|
||||
Limits: internal consistency is not external authentication, hermetic build proof, native usability, a new source comparison or production acceptance. Review exact run results and source identity separately. Run with `python -B` to avoid incidental bytecode writes.
|
||||
Binary file not shown.
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"prepare.py": {
|
||||
"bytes": 6316,
|
||||
"sha256": "aa52592fb8e373c2a90007e187734d29129d38d9fce9dc45461482c7f6376bff"
|
||||
},
|
||||
"verify.py": {
|
||||
"bytes": 11440,
|
||||
"sha256": "584187370a1076e13190914158fc72a9ab65f07e72cc6a0d3b5c319f3dc7f05f"
|
||||
},
|
||||
"README.md": {
|
||||
"bytes": 3284,
|
||||
"sha256": "3ff0a61fb15ca26e54b8903962c99ba7802a87f0204e7b71f2d04c812b9588b7"
|
||||
},
|
||||
"manifest.json": {
|
||||
"bytes": 31065,
|
||||
"sha256": "a993618118369f293569ffdf10c6c05ded4fe8f105df50838c56dca25e0b9eab"
|
||||
},
|
||||
"evidence.zip": {
|
||||
"bytes": 20799621,
|
||||
"sha256": "a3fdde41e8e8cb4c2c2381a28628b5c9687461c18a17008bb1294a33ab962bfd"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,719 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"kind": "allocation-multiselect-cargo-gates",
|
||||
"runs": {
|
||||
"experiment-1": {
|
||||
"command": [
|
||||
"cargo",
|
||||
"test",
|
||||
"-p",
|
||||
"oa-desktop",
|
||||
"--bin",
|
||||
"arcadia-studio",
|
||||
"--message-format=json",
|
||||
"--",
|
||||
"mixed_arrange_experiment",
|
||||
"--nocapture",
|
||||
"--test-threads=1"
|
||||
],
|
||||
"head": "6d99aacab8ca1a91c857a2179baa14d80a2901e9",
|
||||
"exitCode": 0,
|
||||
"inputCount": 743,
|
||||
"helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py",
|
||||
"sourceProof": {
|
||||
"commit": "3a7923b96d671041cbc747a614cbd0fad6b6b3d3",
|
||||
"pin": {
|
||||
"bytes": 591,
|
||||
"sha256": "ca8e9265a34d465c365a5ba1472d80fef8720a4fb56d82dc7cfaa0a7fa9e391b"
|
||||
},
|
||||
"comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py"
|
||||
}
|
||||
},
|
||||
"experiment-2": {
|
||||
"command": [
|
||||
"cargo",
|
||||
"test",
|
||||
"-p",
|
||||
"oa-desktop",
|
||||
"--example",
|
||||
"allocation_policy_probe",
|
||||
"--message-format=json",
|
||||
"--",
|
||||
"mixed_arrange_experiment",
|
||||
"--nocapture",
|
||||
"--test-threads=1"
|
||||
],
|
||||
"head": "3a7923b96d671041cbc747a614cbd0fad6b6b3d3",
|
||||
"exitCode": 101,
|
||||
"inputCount": 744,
|
||||
"helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py"
|
||||
},
|
||||
"experiment-3": {
|
||||
"command": [
|
||||
"cargo",
|
||||
"test",
|
||||
"-p",
|
||||
"oa-desktop",
|
||||
"--example",
|
||||
"allocation_policy_probe",
|
||||
"--message-format=json",
|
||||
"--",
|
||||
"mixed_arrange_experiment",
|
||||
"--nocapture",
|
||||
"--test-threads=1"
|
||||
],
|
||||
"head": "3a7923b96d671041cbc747a614cbd0fad6b6b3d3",
|
||||
"exitCode": 0,
|
||||
"inputCount": 744,
|
||||
"helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py",
|
||||
"sourceProof": {
|
||||
"commit": "8dbbaf262e3b8d26a32d6c30f0cc5f963fab47a0",
|
||||
"pin": {
|
||||
"bytes": 591,
|
||||
"sha256": "e1e330d2dc4fee475991d0ba1a1bb75fae77c13d5874689af26987be12db0aae"
|
||||
},
|
||||
"comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py"
|
||||
}
|
||||
},
|
||||
"planner-document-1": {
|
||||
"command": [
|
||||
"cargo",
|
||||
"test",
|
||||
"-p",
|
||||
"oa-desktop",
|
||||
"--example",
|
||||
"allocation_policy_probe",
|
||||
"--message-format=json",
|
||||
"--",
|
||||
"--test-threads=1"
|
||||
],
|
||||
"head": "3a7923b96d671041cbc747a614cbd0fad6b6b3d3",
|
||||
"exitCode": 0,
|
||||
"inputCount": 744,
|
||||
"helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py",
|
||||
"sourceProof": {
|
||||
"commit": "8dbbaf262e3b8d26a32d6c30f0cc5f963fab47a0",
|
||||
"pin": {
|
||||
"bytes": 597,
|
||||
"sha256": "c64e4c556e27e6a6fbc8be463738783bcd5afa40959d4cec87801a53c8b08773"
|
||||
},
|
||||
"comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py"
|
||||
}
|
||||
},
|
||||
"probe-lint-1": {
|
||||
"command": [
|
||||
"cargo",
|
||||
"clippy",
|
||||
"-p",
|
||||
"oa-desktop",
|
||||
"--example",
|
||||
"allocation_policy_probe",
|
||||
"--tests",
|
||||
"--message-format=json",
|
||||
"--",
|
||||
"-D",
|
||||
"warnings"
|
||||
],
|
||||
"head": "3a7923b96d671041cbc747a614cbd0fad6b6b3d3",
|
||||
"exitCode": 0,
|
||||
"inputCount": 744,
|
||||
"helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py",
|
||||
"sourceProof": {
|
||||
"commit": "8dbbaf262e3b8d26a32d6c30f0cc5f963fab47a0",
|
||||
"pin": {
|
||||
"bytes": 591,
|
||||
"sha256": "d49e047e0bfe3591836e702141be0f3935b94ecff11d5eb4bcd26658e153ccb8"
|
||||
},
|
||||
"comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py"
|
||||
}
|
||||
},
|
||||
"format-1": {
|
||||
"command": [
|
||||
"cargo",
|
||||
"fmt",
|
||||
"--all",
|
||||
"--",
|
||||
"--check"
|
||||
],
|
||||
"head": "3a7923b96d671041cbc747a614cbd0fad6b6b3d3",
|
||||
"exitCode": 0,
|
||||
"inputCount": 744,
|
||||
"helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py",
|
||||
"sourceProof": {
|
||||
"commit": "8dbbaf262e3b8d26a32d6c30f0cc5f963fab47a0",
|
||||
"pin": {
|
||||
"bytes": 587,
|
||||
"sha256": "26071a3c7f146022eebe2f22c50debf0c5f3f554cd561516d1a473be31a88f0d"
|
||||
},
|
||||
"comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py"
|
||||
}
|
||||
},
|
||||
"arrange-planner-1": {
|
||||
"command": [
|
||||
"cargo",
|
||||
"test",
|
||||
"-p",
|
||||
"oa-desktop",
|
||||
"--example",
|
||||
"allocation_policy_probe",
|
||||
"--message-format=json",
|
||||
"--",
|
||||
"--test-threads=1"
|
||||
],
|
||||
"head": "8dbbaf262e3b8d26a32d6c30f0cc5f963fab47a0",
|
||||
"exitCode": 101,
|
||||
"inputCount": 746,
|
||||
"helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py"
|
||||
},
|
||||
"arrange-planner-2": {
|
||||
"command": [
|
||||
"cargo",
|
||||
"test",
|
||||
"-p",
|
||||
"oa-desktop",
|
||||
"--example",
|
||||
"allocation_policy_probe",
|
||||
"--message-format=json",
|
||||
"--",
|
||||
"--test-threads=1"
|
||||
],
|
||||
"head": "8dbbaf262e3b8d26a32d6c30f0cc5f963fab47a0",
|
||||
"exitCode": 101,
|
||||
"inputCount": 746,
|
||||
"helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py"
|
||||
},
|
||||
"arrange-planner-3": {
|
||||
"command": [
|
||||
"cargo",
|
||||
"test",
|
||||
"-p",
|
||||
"oa-desktop",
|
||||
"--example",
|
||||
"allocation_policy_probe",
|
||||
"--message-format=json",
|
||||
"--",
|
||||
"--test-threads=1"
|
||||
],
|
||||
"head": "8dbbaf262e3b8d26a32d6c30f0cc5f963fab47a0",
|
||||
"exitCode": 0,
|
||||
"inputCount": 746,
|
||||
"helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py"
|
||||
},
|
||||
"arrange-planner-4": {
|
||||
"command": [
|
||||
"cargo",
|
||||
"test",
|
||||
"-p",
|
||||
"oa-desktop",
|
||||
"--example",
|
||||
"allocation_policy_probe",
|
||||
"--message-format=json",
|
||||
"--",
|
||||
"--test-threads=1"
|
||||
],
|
||||
"head": "8dbbaf262e3b8d26a32d6c30f0cc5f963fab47a0",
|
||||
"exitCode": 0,
|
||||
"inputCount": 746,
|
||||
"helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py",
|
||||
"sourceProof": {
|
||||
"commit": "9b83f7ca0dcd34056765b9399863a21da72c3a9f",
|
||||
"pin": {
|
||||
"bytes": 596,
|
||||
"sha256": "cbf8c9171bb6debd47397e48a62231f8295f86c7b79bfd3c36ad885689c742e6"
|
||||
},
|
||||
"comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py"
|
||||
}
|
||||
},
|
||||
"arrange-lint-1": {
|
||||
"command": [
|
||||
"cargo",
|
||||
"clippy",
|
||||
"-p",
|
||||
"oa-desktop",
|
||||
"--example",
|
||||
"allocation_policy_probe",
|
||||
"--tests",
|
||||
"--message-format=json",
|
||||
"--",
|
||||
"-D",
|
||||
"warnings"
|
||||
],
|
||||
"head": "8dbbaf262e3b8d26a32d6c30f0cc5f963fab47a0",
|
||||
"exitCode": 0,
|
||||
"inputCount": 746,
|
||||
"helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py",
|
||||
"sourceProof": {
|
||||
"commit": "9b83f7ca0dcd34056765b9399863a21da72c3a9f",
|
||||
"pin": {
|
||||
"bytes": 593,
|
||||
"sha256": "d476324a632b56df88343b7bc90c89fc14ee70b30fe91c0be55de01c0de5c846"
|
||||
},
|
||||
"comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py"
|
||||
}
|
||||
},
|
||||
"arrange-format-1": {
|
||||
"command": [
|
||||
"cargo",
|
||||
"fmt",
|
||||
"--all",
|
||||
"--",
|
||||
"--check"
|
||||
],
|
||||
"head": "9b83f7ca0dcd34056765b9399863a21da72c3a9f",
|
||||
"exitCode": 0,
|
||||
"inputCount": 746,
|
||||
"helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py",
|
||||
"sourceProof": {
|
||||
"commit": "9b83f7ca0dcd34056765b9399863a21da72c3a9f",
|
||||
"pin": {
|
||||
"bytes": 595,
|
||||
"sha256": "03ae19dca92db8cdde62c5a0f63c6c5789d75a977079bbd1d84c76c91d775f08"
|
||||
},
|
||||
"comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py"
|
||||
}
|
||||
}
|
||||
},
|
||||
"captureHelpers": {
|
||||
"gate.py": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py",
|
||||
"source-proof.py": "helpers/58597566ae1cb5c4021ddc7e86635b76d127bdb63b5d3026c427771aae7e2119.py"
|
||||
},
|
||||
"logicalFiles": {
|
||||
"cargo/arrange-format-1/inputs.json": "capsules/c8192fd84fba63fa576975e9fd44f0fa2d6c8ed2e6b5ada3fd4bee076d36f686.json",
|
||||
"cargo/arrange-format-1/inputs.zip": "capsules/29ab4dce454ec8dd92208620e6f8eb0749b6fd72c1687bf1d19264c77159e4f1.zip",
|
||||
"cargo/arrange-format-1/process.json": "cargo/arrange-format-1/process.json",
|
||||
"cargo/arrange-format-1/result.json": "cargo/arrange-format-1/result.json",
|
||||
"cargo/arrange-format-1/source-proof.json": "cargo/arrange-format-1/source-proof.json",
|
||||
"cargo/arrange-format-1/started.json": "cargo/arrange-format-1/started.json",
|
||||
"cargo/arrange-format-1/stderr.log": "cargo/arrange-format-1/stderr.log",
|
||||
"cargo/arrange-format-1/stdout.log": "cargo/arrange-format-1/stdout.log",
|
||||
"cargo/arrange-lint-1/inputs.json": "capsules/c8192fd84fba63fa576975e9fd44f0fa2d6c8ed2e6b5ada3fd4bee076d36f686.json",
|
||||
"cargo/arrange-lint-1/inputs.zip": "capsules/29ab4dce454ec8dd92208620e6f8eb0749b6fd72c1687bf1d19264c77159e4f1.zip",
|
||||
"cargo/arrange-lint-1/process.json": "cargo/arrange-lint-1/process.json",
|
||||
"cargo/arrange-lint-1/result.json": "cargo/arrange-lint-1/result.json",
|
||||
"cargo/arrange-lint-1/source-proof.json": "cargo/arrange-lint-1/source-proof.json",
|
||||
"cargo/arrange-lint-1/started.json": "cargo/arrange-lint-1/started.json",
|
||||
"cargo/arrange-lint-1/stderr.log": "cargo/arrange-lint-1/stderr.log",
|
||||
"cargo/arrange-lint-1/stdout.log": "cargo/arrange-lint-1/stdout.log",
|
||||
"cargo/arrange-planner-1/inputs.json": "capsules/084e4bd0288b35761193f3e28cdc580fa545de80f9147ef0ba997d090f0ba2a1.json",
|
||||
"cargo/arrange-planner-1/inputs.zip": "capsules/3c0175ff95e0639f8e400e41f6014f8b0223672494682b4f39a8ca8d45ff898f.zip",
|
||||
"cargo/arrange-planner-1/process.json": "cargo/arrange-planner-1/process.json",
|
||||
"cargo/arrange-planner-1/result.json": "cargo/arrange-planner-1/result.json",
|
||||
"cargo/arrange-planner-1/started.json": "cargo/arrange-planner-1/started.json",
|
||||
"cargo/arrange-planner-1/stderr.log": "cargo/arrange-planner-1/stderr.log",
|
||||
"cargo/arrange-planner-1/stdout.log": "cargo/arrange-planner-1/stdout.log",
|
||||
"cargo/arrange-planner-2/inputs.json": "capsules/f2ffd9ca8ee08a31769e1a5f460f5edd1a78e539463e25c1dcec8c7065829619.json",
|
||||
"cargo/arrange-planner-2/inputs.zip": "capsules/5c2134898d477eca46ed26eff9a9833de4005660eb7ee89a124eacba21a9b18e.zip",
|
||||
"cargo/arrange-planner-2/process.json": "cargo/arrange-planner-2/process.json",
|
||||
"cargo/arrange-planner-2/result.json": "cargo/arrange-planner-2/result.json",
|
||||
"cargo/arrange-planner-2/started.json": "cargo/arrange-planner-2/started.json",
|
||||
"cargo/arrange-planner-2/stderr.log": "cargo/arrange-planner-2/stderr.log",
|
||||
"cargo/arrange-planner-2/stdout.log": "cargo/arrange-planner-2/stdout.log",
|
||||
"cargo/arrange-planner-3/inputs.json": "capsules/d918a5797a645d1483139139b1a56a558f5c54fe5f797433cbaa7ed5c34c07a0.json",
|
||||
"cargo/arrange-planner-3/inputs.zip": "capsules/0b08fc45ecc1d38421d9c5b42e65d2b577d4641d0addb0e04043815e76b4b50f.zip",
|
||||
"cargo/arrange-planner-3/process.json": "cargo/arrange-planner-3/process.json",
|
||||
"cargo/arrange-planner-3/result.json": "cargo/arrange-planner-3/result.json",
|
||||
"cargo/arrange-planner-3/started.json": "cargo/arrange-planner-3/started.json",
|
||||
"cargo/arrange-planner-3/stderr.log": "cargo/arrange-planner-3/stderr.log",
|
||||
"cargo/arrange-planner-3/stdout.log": "cargo/arrange-planner-3/stdout.log",
|
||||
"cargo/arrange-planner-4/inputs.json": "capsules/c8192fd84fba63fa576975e9fd44f0fa2d6c8ed2e6b5ada3fd4bee076d36f686.json",
|
||||
"cargo/arrange-planner-4/inputs.zip": "capsules/29ab4dce454ec8dd92208620e6f8eb0749b6fd72c1687bf1d19264c77159e4f1.zip",
|
||||
"cargo/arrange-planner-4/process.json": "cargo/arrange-planner-4/process.json",
|
||||
"cargo/arrange-planner-4/result.json": "cargo/arrange-planner-4/result.json",
|
||||
"cargo/arrange-planner-4/source-proof.json": "cargo/arrange-planner-4/source-proof.json",
|
||||
"cargo/arrange-planner-4/started.json": "cargo/arrange-planner-4/started.json",
|
||||
"cargo/arrange-planner-4/stderr.log": "cargo/arrange-planner-4/stderr.log",
|
||||
"cargo/arrange-planner-4/stdout.log": "cargo/arrange-planner-4/stdout.log",
|
||||
"cargo/experiment-1/inputs.json": "capsules/fc74b619bba31bed7a075cf519456d32f7ccffd1e06624bdb92ad309d55cac45.json",
|
||||
"cargo/experiment-1/inputs.zip": "capsules/f2e0d3cfeff569cc7794d56f1c439ae1fe1eac15269ee0c8edd58bc80aacaa2d.zip",
|
||||
"cargo/experiment-1/process.json": "cargo/experiment-1/process.json",
|
||||
"cargo/experiment-1/result.json": "cargo/experiment-1/result.json",
|
||||
"cargo/experiment-1/source-proof.json": "cargo/experiment-1/source-proof.json",
|
||||
"cargo/experiment-1/started.json": "cargo/experiment-1/started.json",
|
||||
"cargo/experiment-1/stderr.log": "cargo/experiment-1/stderr.log",
|
||||
"cargo/experiment-1/stdout.log": "cargo/experiment-1/stdout.log",
|
||||
"cargo/experiment-2/inputs.json": "capsules/4e26f58e200b8c7b825f3c96e2f1df0bdc56f9f02aa8e1d58866b00a81275cdc.json",
|
||||
"cargo/experiment-2/inputs.zip": "capsules/c2e6e9747e345dba2f35c79b00dd1302c59072a848f18534016acf2e81454acd.zip",
|
||||
"cargo/experiment-2/process.json": "cargo/experiment-2/process.json",
|
||||
"cargo/experiment-2/result.json": "cargo/experiment-2/result.json",
|
||||
"cargo/experiment-2/started.json": "cargo/experiment-2/started.json",
|
||||
"cargo/experiment-2/stderr.log": "cargo/experiment-2/stderr.log",
|
||||
"cargo/experiment-2/stdout.log": "cargo/experiment-2/stdout.log",
|
||||
"cargo/experiment-3/inputs.json": "capsules/acd1c8c1f4f2f529455431bbe4193acb25ab8d69bf72ff543265007847b808eb.json",
|
||||
"cargo/experiment-3/inputs.zip": "capsules/8fd3ea41c3f5278bbb3986de804cc93229084b00096c131acd09ba8705db502e.zip",
|
||||
"cargo/experiment-3/process.json": "cargo/experiment-3/process.json",
|
||||
"cargo/experiment-3/result.json": "cargo/experiment-3/result.json",
|
||||
"cargo/experiment-3/source-proof.json": "cargo/experiment-3/source-proof.json",
|
||||
"cargo/experiment-3/started.json": "cargo/experiment-3/started.json",
|
||||
"cargo/experiment-3/stderr.log": "cargo/experiment-3/stderr.log",
|
||||
"cargo/experiment-3/stdout.log": "cargo/experiment-3/stdout.log",
|
||||
"cargo/format-1/inputs.json": "capsules/acd1c8c1f4f2f529455431bbe4193acb25ab8d69bf72ff543265007847b808eb.json",
|
||||
"cargo/format-1/inputs.zip": "capsules/8fd3ea41c3f5278bbb3986de804cc93229084b00096c131acd09ba8705db502e.zip",
|
||||
"cargo/format-1/process.json": "cargo/format-1/process.json",
|
||||
"cargo/format-1/result.json": "cargo/format-1/result.json",
|
||||
"cargo/format-1/source-proof.json": "cargo/format-1/source-proof.json",
|
||||
"cargo/format-1/started.json": "cargo/format-1/started.json",
|
||||
"cargo/format-1/stderr.log": "cargo/format-1/stderr.log",
|
||||
"cargo/format-1/stdout.log": "cargo/format-1/stdout.log",
|
||||
"cargo/planner-document-1/inputs.json": "capsules/acd1c8c1f4f2f529455431bbe4193acb25ab8d69bf72ff543265007847b808eb.json",
|
||||
"cargo/planner-document-1/inputs.zip": "capsules/8fd3ea41c3f5278bbb3986de804cc93229084b00096c131acd09ba8705db502e.zip",
|
||||
"cargo/planner-document-1/process.json": "cargo/planner-document-1/process.json",
|
||||
"cargo/planner-document-1/result.json": "cargo/planner-document-1/result.json",
|
||||
"cargo/planner-document-1/source-proof.json": "cargo/planner-document-1/source-proof.json",
|
||||
"cargo/planner-document-1/started.json": "cargo/planner-document-1/started.json",
|
||||
"cargo/planner-document-1/stderr.log": "cargo/planner-document-1/stderr.log",
|
||||
"cargo/planner-document-1/stdout.log": "cargo/planner-document-1/stdout.log",
|
||||
"cargo/probe-lint-1/inputs.json": "capsules/acd1c8c1f4f2f529455431bbe4193acb25ab8d69bf72ff543265007847b808eb.json",
|
||||
"cargo/probe-lint-1/inputs.zip": "capsules/8fd3ea41c3f5278bbb3986de804cc93229084b00096c131acd09ba8705db502e.zip",
|
||||
"cargo/probe-lint-1/process.json": "cargo/probe-lint-1/process.json",
|
||||
"cargo/probe-lint-1/result.json": "cargo/probe-lint-1/result.json",
|
||||
"cargo/probe-lint-1/source-proof.json": "cargo/probe-lint-1/source-proof.json",
|
||||
"cargo/probe-lint-1/started.json": "cargo/probe-lint-1/started.json",
|
||||
"cargo/probe-lint-1/stderr.log": "cargo/probe-lint-1/stderr.log",
|
||||
"cargo/probe-lint-1/stdout.log": "cargo/probe-lint-1/stdout.log",
|
||||
"comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py",
|
||||
"helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py",
|
||||
"helpers/58597566ae1cb5c4021ddc7e86635b76d127bdb63b5d3026c427771aae7e2119.py": "helpers/58597566ae1cb5c4021ddc7e86635b76d127bdb63b5d3026c427771aae7e2119.py"
|
||||
},
|
||||
"members": {
|
||||
"capsules/084e4bd0288b35761193f3e28cdc580fa545de80f9147ef0ba997d090f0ba2a1.json": {
|
||||
"bytes": 124966,
|
||||
"sha256": "084e4bd0288b35761193f3e28cdc580fa545de80f9147ef0ba997d090f0ba2a1"
|
||||
},
|
||||
"capsules/0b08fc45ecc1d38421d9c5b42e65d2b577d4641d0addb0e04043815e76b4b50f.zip": {
|
||||
"bytes": 2998637,
|
||||
"sha256": "0b08fc45ecc1d38421d9c5b42e65d2b577d4641d0addb0e04043815e76b4b50f"
|
||||
},
|
||||
"capsules/29ab4dce454ec8dd92208620e6f8eb0749b6fd72c1687bf1d19264c77159e4f1.zip": {
|
||||
"bytes": 2999625,
|
||||
"sha256": "29ab4dce454ec8dd92208620e6f8eb0749b6fd72c1687bf1d19264c77159e4f1"
|
||||
},
|
||||
"capsules/3c0175ff95e0639f8e400e41f6014f8b0223672494682b4f39a8ca8d45ff898f.zip": {
|
||||
"bytes": 2998617,
|
||||
"sha256": "3c0175ff95e0639f8e400e41f6014f8b0223672494682b4f39a8ca8d45ff898f"
|
||||
},
|
||||
"capsules/4e26f58e200b8c7b825f3c96e2f1df0bdc56f9f02aa8e1d58866b00a81275cdc.json": {
|
||||
"bytes": 124628,
|
||||
"sha256": "4e26f58e200b8c7b825f3c96e2f1df0bdc56f9f02aa8e1d58866b00a81275cdc"
|
||||
},
|
||||
"capsules/5c2134898d477eca46ed26eff9a9833de4005660eb7ee89a124eacba21a9b18e.zip": {
|
||||
"bytes": 2998623,
|
||||
"sha256": "5c2134898d477eca46ed26eff9a9833de4005660eb7ee89a124eacba21a9b18e"
|
||||
},
|
||||
"capsules/8fd3ea41c3f5278bbb3986de804cc93229084b00096c131acd09ba8705db502e.zip": {
|
||||
"bytes": 2992280,
|
||||
"sha256": "8fd3ea41c3f5278bbb3986de804cc93229084b00096c131acd09ba8705db502e"
|
||||
},
|
||||
"capsules/acd1c8c1f4f2f529455431bbe4193acb25ab8d69bf72ff543265007847b808eb.json": {
|
||||
"bytes": 124628,
|
||||
"sha256": "acd1c8c1f4f2f529455431bbe4193acb25ab8d69bf72ff543265007847b808eb"
|
||||
},
|
||||
"capsules/c2e6e9747e345dba2f35c79b00dd1302c59072a848f18534016acf2e81454acd.zip": {
|
||||
"bytes": 2992231,
|
||||
"sha256": "c2e6e9747e345dba2f35c79b00dd1302c59072a848f18534016acf2e81454acd"
|
||||
},
|
||||
"capsules/c8192fd84fba63fa576975e9fd44f0fa2d6c8ed2e6b5ada3fd4bee076d36f686.json": {
|
||||
"bytes": 124966,
|
||||
"sha256": "c8192fd84fba63fa576975e9fd44f0fa2d6c8ed2e6b5ada3fd4bee076d36f686"
|
||||
},
|
||||
"capsules/d918a5797a645d1483139139b1a56a558f5c54fe5f797433cbaa7ed5c34c07a0.json": {
|
||||
"bytes": 124966,
|
||||
"sha256": "d918a5797a645d1483139139b1a56a558f5c54fe5f797433cbaa7ed5c34c07a0"
|
||||
},
|
||||
"capsules/f2e0d3cfeff569cc7794d56f1c439ae1fe1eac15269ee0c8edd58bc80aacaa2d.zip": {
|
||||
"bytes": 2990212,
|
||||
"sha256": "f2e0d3cfeff569cc7794d56f1c439ae1fe1eac15269ee0c8edd58bc80aacaa2d"
|
||||
},
|
||||
"capsules/f2ffd9ca8ee08a31769e1a5f460f5edd1a78e539463e25c1dcec8c7065829619.json": {
|
||||
"bytes": 124966,
|
||||
"sha256": "f2ffd9ca8ee08a31769e1a5f460f5edd1a78e539463e25c1dcec8c7065829619"
|
||||
},
|
||||
"capsules/fc74b619bba31bed7a075cf519456d32f7ccffd1e06624bdb92ad309d55cac45.json": {
|
||||
"bytes": 124458,
|
||||
"sha256": "fc74b619bba31bed7a075cf519456d32f7ccffd1e06624bdb92ad309d55cac45"
|
||||
},
|
||||
"cargo/arrange-format-1/process.json": {
|
||||
"bytes": 116,
|
||||
"sha256": "2eb27eb4ad4b1d6cdb493ece9df3247de50b4f494522a7fc0cd75cf286847507"
|
||||
},
|
||||
"cargo/arrange-format-1/result.json": {
|
||||
"bytes": 1871,
|
||||
"sha256": "a5f6e31729519aa3fc064d675731a79c9d93297f713a39afad04de9c8fedeaa8"
|
||||
},
|
||||
"cargo/arrange-format-1/source-proof.json": {
|
||||
"bytes": 595,
|
||||
"sha256": "03ae19dca92db8cdde62c5a0f63c6c5789d75a977079bbd1d84c76c91d775f08"
|
||||
},
|
||||
"cargo/arrange-format-1/started.json": {
|
||||
"bytes": 1483,
|
||||
"sha256": "098fd74217e751dc4aa4767f6d59b24ca65bc834dfe7a9dee8330f557baef8ce"
|
||||
},
|
||||
"cargo/arrange-format-1/stderr.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"cargo/arrange-format-1/stdout.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"cargo/arrange-lint-1/process.json": {
|
||||
"bytes": 213,
|
||||
"sha256": "930d2a3b839ac22ae66dbf283634878a90bff77cd3f21c3efbefed87d2561f1b"
|
||||
},
|
||||
"cargo/arrange-lint-1/result.json": {
|
||||
"bytes": 2005,
|
||||
"sha256": "278a880fc03cd922c0055b84cf364c0f17ee6217f0cfa1d75ca3f52399e96aad"
|
||||
},
|
||||
"cargo/arrange-lint-1/source-proof.json": {
|
||||
"bytes": 593,
|
||||
"sha256": "d476324a632b56df88343b7bc90c89fc14ee70b30fe91c0be55de01c0de5c846"
|
||||
},
|
||||
"cargo/arrange-lint-1/started.json": {
|
||||
"bytes": 1610,
|
||||
"sha256": "8171889b3bebe97b49b4f2214bfe732f2651a1c827c3777ea91fa57235e73fc2"
|
||||
},
|
||||
"cargo/arrange-lint-1/stderr.log": {
|
||||
"bytes": 137,
|
||||
"sha256": "412177405c27599386afb28d603f0895c31becfc6b6de4ebb5a4063734ba94a7"
|
||||
},
|
||||
"cargo/arrange-lint-1/stdout.log": {
|
||||
"bytes": 268845,
|
||||
"sha256": "f6b71a7a22bd4af2205cde4becc7e1e017ad4d78013944cb2b5218fc32d2e4b8"
|
||||
},
|
||||
"cargo/arrange-planner-1/process.json": {
|
||||
"bytes": 202,
|
||||
"sha256": "ffeb3bed75938dc4335bd6253783601f21c72999cad952dd191ca7243bf4c506"
|
||||
},
|
||||
"cargo/arrange-planner-1/result.json": {
|
||||
"bytes": 1987,
|
||||
"sha256": "6e71d9a4f75ce5aeb7714aeffb23f622d4b3a1b267601e45368fcc3597742f47"
|
||||
},
|
||||
"cargo/arrange-planner-1/started.json": {
|
||||
"bytes": 1589,
|
||||
"sha256": "be88ce011f96d06e07ba02b5e485fe365940a8fb8aa19158ba82e46f5abbb94c"
|
||||
},
|
||||
"cargo/arrange-planner-1/stderr.log": {
|
||||
"bytes": 179,
|
||||
"sha256": "fff43766ea766c831cd1963c57fd67791b065badb93ec96b62e8546233f3109c"
|
||||
},
|
||||
"cargo/arrange-planner-1/stdout.log": {
|
||||
"bytes": 295296,
|
||||
"sha256": "427033f5308ecb85e754d6a5fc21ea56d0276edaa0d0d0bf41bf234d9cb452e1"
|
||||
},
|
||||
"cargo/arrange-planner-2/process.json": {
|
||||
"bytes": 202,
|
||||
"sha256": "d1e6c39dcdf512da2c2ad457200cd14d3f989048d0244c7eb784c7547f2db63f"
|
||||
},
|
||||
"cargo/arrange-planner-2/result.json": {
|
||||
"bytes": 1987,
|
||||
"sha256": "ccea0caeaf49f4bb0db9ac790cac9fef2138cff072c4d7104fea5597412260b3"
|
||||
},
|
||||
"cargo/arrange-planner-2/started.json": {
|
||||
"bytes": 1589,
|
||||
"sha256": "22c4c2579b3d16b61929323cb7f8c2be55f4402d8091dcba20b3dc539cb65b87"
|
||||
},
|
||||
"cargo/arrange-planner-2/stderr.log": {
|
||||
"bytes": 180,
|
||||
"sha256": "e96d24ab1396169886e66c47bfc8ad423c47eb1ba04f23cb0b993a42fcd00672"
|
||||
},
|
||||
"cargo/arrange-planner-2/stdout.log": {
|
||||
"bytes": 304852,
|
||||
"sha256": "b1de0cb57b6c9d8a1163635bb9428c9058989f3a3e04f771c6d52ec3e98bb38d"
|
||||
},
|
||||
"cargo/arrange-planner-3/process.json": {
|
||||
"bytes": 202,
|
||||
"sha256": "3d40643702d3e4cd5f1c77665d6a6fe7489a8962ad4831a4bf36176716fc3806"
|
||||
},
|
||||
"cargo/arrange-planner-3/result.json": {
|
||||
"bytes": 3388,
|
||||
"sha256": "281bd88cc0e8908b12e11ca8c32c87b904e9aa511022d5737aa208f6d09d5516"
|
||||
},
|
||||
"cargo/arrange-planner-3/started.json": {
|
||||
"bytes": 1589,
|
||||
"sha256": "97f7f2fb041de0bcfb4c55fc998c33181d50a15aad3f1ef9d98e9f8ae81c91af"
|
||||
},
|
||||
"cargo/arrange-planner-3/stderr.log": {
|
||||
"bytes": 323,
|
||||
"sha256": "c02d99f2243e3b34e2ca3512d4b18ecd60cd27eb1066e2336df3f88908ef26af"
|
||||
},
|
||||
"cargo/arrange-planner-3/stdout.log": {
|
||||
"bytes": 300602,
|
||||
"sha256": "b681a64a77fb83078b2aef1035c3ce5a7a7fc4c0cc439795eb5ad476216a8bea"
|
||||
},
|
||||
"cargo/arrange-planner-4/process.json": {
|
||||
"bytes": 202,
|
||||
"sha256": "ce53d413817d6ba48cd361c9d97989c65f53b9ced8fa772870c0162a0725c44b"
|
||||
},
|
||||
"cargo/arrange-planner-4/result.json": {
|
||||
"bytes": 3388,
|
||||
"sha256": "71ff6ed0ff007f15dc0c9d574981c7fb765771baa0370b69f2868822c3b0cd76"
|
||||
},
|
||||
"cargo/arrange-planner-4/source-proof.json": {
|
||||
"bytes": 596,
|
||||
"sha256": "cbf8c9171bb6debd47397e48a62231f8295f86c7b79bfd3c36ad885689c742e6"
|
||||
},
|
||||
"cargo/arrange-planner-4/started.json": {
|
||||
"bytes": 1589,
|
||||
"sha256": "9686ab1af2b7131de0656d131eadb217b869eeeeeef860c94025e42c4a102ae7"
|
||||
},
|
||||
"cargo/arrange-planner-4/stderr.log": {
|
||||
"bytes": 324,
|
||||
"sha256": "8ba7a613f49ce57efa9a35742c9bfe8acf9c1536ebb9a9f1873f5d0ca9a3301b"
|
||||
},
|
||||
"cargo/arrange-planner-4/stdout.log": {
|
||||
"bytes": 300969,
|
||||
"sha256": "e0cd9d35beeb9f48ee7e97fee96d7bda700c96786a1c7199c4c38170d9b71bc2"
|
||||
},
|
||||
"cargo/experiment-1/process.json": {
|
||||
"bytes": 232,
|
||||
"sha256": "021352da56436e72c00da14992f8a94d26efd0893af5d7230b97d1f0af97927a"
|
||||
},
|
||||
"cargo/experiment-1/result.json": {
|
||||
"bytes": 3364,
|
||||
"sha256": "a82c43d59954773907d5268395e40c9829793fb2d4db5387cb306fd5b39edd01"
|
||||
},
|
||||
"cargo/experiment-1/source-proof.json": {
|
||||
"bytes": 591,
|
||||
"sha256": "ca8e9265a34d465c365a5ba1472d80fef8720a4fb56d82dc7cfaa0a7fa9e391b"
|
||||
},
|
||||
"cargo/experiment-1/started.json": {
|
||||
"bytes": 1629,
|
||||
"sha256": "b2bd9e31d8242956809a0d3b6a3cf506f910539d776d9cc0c8131102b1846081"
|
||||
},
|
||||
"cargo/experiment-1/stderr.log": {
|
||||
"bytes": 288,
|
||||
"sha256": "c8e5c4c82f33c431eca2fdec4dee37250fcaadd4871cb896520ee779a3523924"
|
||||
},
|
||||
"cargo/experiment-1/stdout.log": {
|
||||
"bytes": 293505,
|
||||
"sha256": "a5fb7e62505efc44ff3d17f11437ede717eedd05e639d9c19db8e80d52699c70"
|
||||
},
|
||||
"cargo/experiment-2/process.json": {
|
||||
"bytes": 245,
|
||||
"sha256": "2b60185d235cf572b2a1ed79795dbf0868fbc6cfc532edd895d51dd09eb889cd"
|
||||
},
|
||||
"cargo/experiment-2/result.json": {
|
||||
"bytes": 2040,
|
||||
"sha256": "746b1a53511248914d647ac51db2c222d7378cedc7e59e91ef8beea8eb043315"
|
||||
},
|
||||
"cargo/experiment-2/started.json": {
|
||||
"bytes": 1642,
|
||||
"sha256": "4cd8ca5c534c16594c52e4fe46f641652e88146afbf025c63a140670cd3e6174"
|
||||
},
|
||||
"cargo/experiment-2/stderr.log": {
|
||||
"bytes": 200,
|
||||
"sha256": "75cc2e0e245d1c80b04a4a2c2d822a925df836958c4b5c887c1a8f11f99f1f63"
|
||||
},
|
||||
"cargo/experiment-2/stdout.log": {
|
||||
"bytes": 355372,
|
||||
"sha256": "c513f481adcaedc4461b2d37ea2a30a72b1b49d20cf66fce587bdbead9cdc3fa"
|
||||
},
|
||||
"cargo/experiment-3/process.json": {
|
||||
"bytes": 245,
|
||||
"sha256": "159f9bea3bea574f63fd1f2a505e245c1839ded6943abf33f0228a08b55f7b9a"
|
||||
},
|
||||
"cargo/experiment-3/result.json": {
|
||||
"bytes": 3439,
|
||||
"sha256": "dffdc1b4b417888f83c87118e981be7a9aa5b1a1dfddb9c3a166ac149013f937"
|
||||
},
|
||||
"cargo/experiment-3/source-proof.json": {
|
||||
"bytes": 591,
|
||||
"sha256": "e1e330d2dc4fee475991d0ba1a1bb75fae77c13d5874689af26987be12db0aae"
|
||||
},
|
||||
"cargo/experiment-3/started.json": {
|
||||
"bytes": 1642,
|
||||
"sha256": "26a7b07180d4a82b3e73ab2bd3435b5dc88f5bf4b3d9657a1e3e4a87e9502415"
|
||||
},
|
||||
"cargo/experiment-3/stderr.log": {
|
||||
"bytes": 323,
|
||||
"sha256": "21871e9ad66301bf27eecf78b22ea4ff2171bf37ed32d5fdc3bd15f1148f6791"
|
||||
},
|
||||
"cargo/experiment-3/stdout.log": {
|
||||
"bytes": 293837,
|
||||
"sha256": "f618b8bff61a3d7dd50d3a427c9a42b4650cedb308752343b3878a997c146e5c"
|
||||
},
|
||||
"cargo/format-1/process.json": {
|
||||
"bytes": 116,
|
||||
"sha256": "e513f657fb6f90a0774e327591f0e5c4e500a36fc09dbbd632758412c5191e31"
|
||||
},
|
||||
"cargo/format-1/result.json": {
|
||||
"bytes": 1872,
|
||||
"sha256": "26947da874f10973bb5f7f00692b354cf1e9680d1a8743d7185ddfbab8ba690a"
|
||||
},
|
||||
"cargo/format-1/source-proof.json": {
|
||||
"bytes": 587,
|
||||
"sha256": "26071a3c7f146022eebe2f22c50debf0c5f3f554cd561516d1a473be31a88f0d"
|
||||
},
|
||||
"cargo/format-1/started.json": {
|
||||
"bytes": 1483,
|
||||
"sha256": "a6cd6be75c5aa87e5dbdebd5e91f1dea44272d5a8bc359133f0bba88093c99d1"
|
||||
},
|
||||
"cargo/format-1/stderr.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"cargo/format-1/stdout.log": {
|
||||
"bytes": 0,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
},
|
||||
"cargo/planner-document-1/process.json": {
|
||||
"bytes": 202,
|
||||
"sha256": "62b9efe10f28e06ae1889aec50c64d08122e7c59498bea461a0d246fd8191f86"
|
||||
},
|
||||
"cargo/planner-document-1/result.json": {
|
||||
"bytes": 3387,
|
||||
"sha256": "c1fcf4c5ba394dd060a7480c6528d3003fbbe28d0393f31f6b29af97ab6e0f96"
|
||||
},
|
||||
"cargo/planner-document-1/source-proof.json": {
|
||||
"bytes": 597,
|
||||
"sha256": "c64e4c556e27e6a6fbc8be463738783bcd5afa40959d4cec87801a53c8b08773"
|
||||
},
|
||||
"cargo/planner-document-1/started.json": {
|
||||
"bytes": 1589,
|
||||
"sha256": "46e446a7aef0bcf53433f6da250773ec1b1180eeebc5423659240d2d9f57993d"
|
||||
},
|
||||
"cargo/planner-document-1/stderr.log": {
|
||||
"bytes": 247,
|
||||
"sha256": "a9712b2a81ccf9c8b139170c92ed4d0477596d634c30fd0b0d71c362fafdff93"
|
||||
},
|
||||
"cargo/planner-document-1/stdout.log": {
|
||||
"bytes": 299855,
|
||||
"sha256": "ce239ba7364a035c08c0bf4c46174d0c0eb63f0bf2e9233bddac2b74e2f31de7"
|
||||
},
|
||||
"cargo/probe-lint-1/process.json": {
|
||||
"bytes": 212,
|
||||
"sha256": "a2bfa1d2452c0ca13feebd54840af0425817d114cd864c04e26c87a5229538a1"
|
||||
},
|
||||
"cargo/probe-lint-1/result.json": {
|
||||
"bytes": 2004,
|
||||
"sha256": "2bdac177fc3ce3c4f6536a3348ec516e0a08fe1a478dd5382b70dc64a41d1385"
|
||||
},
|
||||
"cargo/probe-lint-1/source-proof.json": {
|
||||
"bytes": 591,
|
||||
"sha256": "d49e047e0bfe3591836e702141be0f3935b94ecff11d5eb4bcd26658e153ccb8"
|
||||
},
|
||||
"cargo/probe-lint-1/started.json": {
|
||||
"bytes": 1610,
|
||||
"sha256": "682ae85b82b0551aec98da64192baa124e9dc9b7b2efa302b09cfeec24e395a4"
|
||||
},
|
||||
"cargo/probe-lint-1/stderr.log": {
|
||||
"bytes": 137,
|
||||
"sha256": "6cef38e57b28fdf01ceda8d4115372f4b9957505bbe28f9b6062e6c93c8feebc"
|
||||
},
|
||||
"cargo/probe-lint-1/stdout.log": {
|
||||
"bytes": 268846,
|
||||
"sha256": "38245fd5fc2ba8b6aac057f12438497e67a77a4fe96b2ca6f5aa6e1db36084f5"
|
||||
},
|
||||
"comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py": {
|
||||
"bytes": 10094,
|
||||
"sha256": "7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a"
|
||||
},
|
||||
"helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py": {
|
||||
"bytes": 3827,
|
||||
"sha256": "1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20"
|
||||
},
|
||||
"helpers/58597566ae1cb5c4021ddc7e86635b76d127bdb63b5d3026c427771aae7e2119.py": {
|
||||
"bytes": 1399,
|
||||
"sha256": "58597566ae1cb5c4021ddc7e86635b76d127bdb63b5d3026c427771aae7e2119"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
"""Package explicitly selected closed gate captures without running Cargo."""
|
||||
from pathlib import Path
|
||||
import argparse
|
||||
import json
|
||||
import zipfile
|
||||
from verify import RAW_FILES, pin, parsed, need, run_name, verify_data, verify_package
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
|
||||
|
||||
def collect(root, runs, helpers, comparators=()):
|
||||
gates = root / ".local/allocation-group-gates"
|
||||
candidates = [gates / name for name in ("gate.py", "source-proof.py")] + helpers
|
||||
helper_bytes = [path.read_bytes() for path in candidates]
|
||||
comparator_paths = [root / ".local/process-source-evidence-tools/verify.py", *comparators]
|
||||
comparator_bytes = [path.read_bytes() for path in comparator_paths if path.is_file()]
|
||||
payload, logical, specs = {}, {}, {}
|
||||
def add(name, data):
|
||||
stored = ("capsules/" + pin(data)["sha256"] + Path(name).suffix
|
||||
if name.rsplit("/", 1)[1] in {"inputs.json", "inputs.zip"} else name)
|
||||
need(stored not in payload or payload[stored] == data, "deduplication collision")
|
||||
payload[stored] = data
|
||||
logical[name] = stored
|
||||
helper_catalog = {}
|
||||
for name, data in zip(("gate.py", "source-proof.py"), helper_bytes):
|
||||
helper = "helpers/" + pin(data)["sha256"] + ".py"
|
||||
add(helper, data)
|
||||
helper_catalog[name] = helper
|
||||
for run in runs:
|
||||
folder = gates / run
|
||||
need(folder.is_dir(), "run directory missing: " + run)
|
||||
paths = list(folder.iterdir())
|
||||
names = {path.name for path in paths}
|
||||
need(all(path.is_file() and not path.is_symlink() for path in paths)
|
||||
and names in (RAW_FILES, RAW_FILES | {"source-proof.json"}), "exact closed raw files required: " + run)
|
||||
raw = {path.name: path.read_bytes() for path in paths}
|
||||
result = parsed(raw["result.json"])
|
||||
need("finish" in result and result["inputsUnchanged"] is True, "unfinished/changed run refused: " + run)
|
||||
matches = [data for data in helper_bytes if pin(data) == result["helper"]]
|
||||
need(bool(matches), "exact historical helper unavailable for " + run + "; supply --helper PATH")
|
||||
helper = "helpers/" + result["helper"]["sha256"] + ".py"
|
||||
add(helper, matches[0])
|
||||
for name, data in sorted(raw.items()):
|
||||
add("cargo/" + run + "/" + name, data)
|
||||
specs[run] = {key: result[key] for key in ("command", "head", "exitCode", "inputCount")}
|
||||
specs[run]["helper"] = helper
|
||||
if "source-proof.json" in raw:
|
||||
proof = parsed(raw["source-proof.json"])
|
||||
matches = [data for data in comparator_bytes if pin(data) == proof["comparator"]]
|
||||
need(bool(matches), "exact source comparator unavailable for " + run + "; supply --comparator PATH")
|
||||
comparator = "comparators/" + proof["comparator"]["sha256"] + ".py"
|
||||
add(comparator, matches[0])
|
||||
specs[run]["sourceProof"] = {"commit": proof["commit"], "pin": pin(raw["source-proof.json"]), "comparator": comparator}
|
||||
manifest = {"schema": 1, "kind": "allocation-multiselect-cargo-gates", "runs": specs,
|
||||
"captureHelpers": helper_catalog,
|
||||
"logicalFiles": dict(sorted(logical.items())),
|
||||
"members": {name: pin(data) for name, data in sorted(payload.items())}}
|
||||
summary = verify_data(manifest, payload.__getitem__)
|
||||
return payload, manifest, summary
|
||||
|
||||
|
||||
def write_json(path, value):
|
||||
with path.open("xb") as output:
|
||||
output.write((json.dumps(value, indent=2) + "\n").encode("utf-8"))
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--root", type=Path, required=True, help="checkout holding .local/allocation-group-gates")
|
||||
parser.add_argument("--runs", nargs="+", required=True, help="explicit run names, including failures to retain")
|
||||
parser.add_argument("--helper", type=Path, action="append", default=[], help="additional exact historical helper (repeatable)")
|
||||
parser.add_argument("--comparator", type=Path, action="append", default=[], help="additional exact historical source comparator (repeatable)")
|
||||
parser.add_argument("--output", type=Path, help="fresh, nonexistent package directory (required unless --check-only)")
|
||||
parser.add_argument("--check-only", action="store_true", help="validate raw captures in memory without creating an archive")
|
||||
args = parser.parse_args()
|
||||
need(all(run_name(run) for run in args.runs) and len(args.runs) == len(set(args.runs)), "unique safe run names required")
|
||||
need(args.check_only or args.output is not None, "--output is required unless --check-only")
|
||||
if not args.check_only:
|
||||
need(not args.output.exists(), "output must be a fresh directory: " + str(args.output))
|
||||
payload, manifest, summary = collect(args.root.resolve(), args.runs, args.helper, args.comparator)
|
||||
if args.check_only:
|
||||
print("PASS raw consistency; no package written:", summary)
|
||||
return
|
||||
out = args.output.resolve()
|
||||
out.mkdir(parents=True, exist_ok=False)
|
||||
for name in ("evidence.zip", "manifest.json", "files.json"):
|
||||
need(not (out / name).exists(), "existing package output refused: " + name)
|
||||
for name in ("prepare.py", "verify.py", "README.md"):
|
||||
data = (HERE / name).read_bytes()
|
||||
destination = out / name
|
||||
if destination.exists():
|
||||
need(destination.read_bytes() == data, "different existing package tool: " + name)
|
||||
else:
|
||||
with destination.open("xb") as output:
|
||||
output.write(data)
|
||||
with zipfile.ZipFile(out / "evidence.zip", "x", compression=zipfile.ZIP_DEFLATED, compresslevel=9) as archive:
|
||||
for name, data in sorted(payload.items()):
|
||||
info = zipfile.ZipInfo(name, date_time=(2026, 9, 23, 0, 0, 0))
|
||||
info.compress_type = zipfile.ZIP_DEFLATED
|
||||
info.external_attr = 0o100644 << 16
|
||||
archive.writestr(info, data)
|
||||
write_json(out / "manifest.json", manifest)
|
||||
names = ("prepare.py", "verify.py", "README.md", "manifest.json", "evidence.zip")
|
||||
write_json(out / "files.json", {name: pin((out / name).read_bytes()) for name in names})
|
||||
need(verify_package(out) == summary, "written package differs from validated captures")
|
||||
print("PASS package readback:", out, summary)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,194 @@
|
||||
"""Offline consistency checks only; never execute or extract archived inputs."""
|
||||
from pathlib import Path, PurePosixPath
|
||||
from datetime import datetime
|
||||
import argparse
|
||||
import hashlib
|
||||
import io
|
||||
import json
|
||||
import math
|
||||
import re
|
||||
import stat
|
||||
import zipfile
|
||||
|
||||
RAW_FILES = {"started.json", "process.json", "result.json", "stdout.log", "stderr.log", "inputs.json", "inputs.zip"}
|
||||
OUTER_FILES = {"prepare.py", "verify.py", "README.md", "manifest.json", "evidence.zip"}
|
||||
|
||||
|
||||
def need(condition, message):
|
||||
if not condition:
|
||||
raise ValueError(message)
|
||||
|
||||
|
||||
def pin(data):
|
||||
return {"bytes": len(data), "sha256": hashlib.sha256(data).hexdigest()}
|
||||
|
||||
|
||||
def valid_pin(value):
|
||||
return (isinstance(value, dict) and set(value) == {"bytes", "sha256"}
|
||||
and type(value["bytes"]) is int and value["bytes"] >= 0
|
||||
and isinstance(value["sha256"], str)
|
||||
and re.fullmatch(r"[0-9a-f]{64}", value["sha256"]) is not None)
|
||||
|
||||
|
||||
def safe(name):
|
||||
return (isinstance(name, str) and bool(name) and "\\" not in name and ":" not in name
|
||||
and all(ord(char) >= 32 for char in name)
|
||||
and not PurePosixPath(name).is_absolute()
|
||||
and all(part not in ("", ".", "..") for part in name.split("/")))
|
||||
|
||||
|
||||
def run_name(name):
|
||||
return isinstance(name, str) and re.fullmatch(r"[A-Za-z0-9][A-Za-z0-9._-]*", name) is not None
|
||||
|
||||
|
||||
def parsed(data):
|
||||
def pairs(items):
|
||||
result = {}
|
||||
for key, value in items:
|
||||
need(key not in result, "duplicate JSON key: " + key)
|
||||
result[key] = value
|
||||
return result
|
||||
def constant(value):
|
||||
raise ValueError("nonfinite JSON constant: " + value)
|
||||
return json.loads(data, object_pairs_hook=pairs, parse_constant=constant)
|
||||
|
||||
|
||||
def inventory(archive, expected):
|
||||
names = archive.namelist()
|
||||
need(len(names) == len(set(names)) and set(names) == set(expected), "exact ZIP membership")
|
||||
for entry in archive.infolist():
|
||||
need(safe(entry.filename) and not entry.is_dir(), "unsafe ZIP member: " + entry.filename)
|
||||
need(not stat.S_ISLNK(entry.external_attr >> 16), "ZIP symlink: " + entry.filename)
|
||||
need(valid_pin(expected[entry.filename]), "invalid member pin: " + entry.filename)
|
||||
need(entry.file_size == expected[entry.filename]["bytes"], "ZIP recorded size: " + entry.filename)
|
||||
|
||||
|
||||
def ordered_times(*values):
|
||||
times = [datetime.fromisoformat(value) for value in values]
|
||||
return all(value.utcoffset() is not None for value in times) and times == sorted(times)
|
||||
|
||||
|
||||
def verify_data(manifest, read):
|
||||
"""Shared read-only verifier for packaged bytes or prepare's in-memory payload."""
|
||||
need(manifest["schema"] == 1 and manifest["kind"] == "allocation-multiselect-cargo-gates", "manifest schema")
|
||||
runs, logical, stored = manifest["runs"], manifest["logicalFiles"], manifest["members"]
|
||||
helpers = manifest["captureHelpers"]
|
||||
need(isinstance(helpers, dict) and set(helpers) == {"gate.py", "source-proof.py"}, "capture helper names")
|
||||
need(all(isinstance(name, str) and re.fullmatch(r"helpers/[0-9a-f]{64}\.py", name)
|
||||
for name in helpers.values()), "capture helper mapping")
|
||||
need(isinstance(runs, dict) and bool(runs) and all(run_name(run) for run in runs), "explicit run inventory")
|
||||
need(all(safe(name) for name in logical) and all(safe(name) for name in stored), "unsafe manifest path")
|
||||
need(set(logical.values()) == set(stored), "unreferenced or absent stored members")
|
||||
for name, expected in stored.items():
|
||||
need(valid_pin(expected) and pin(read(name)) == expected, "stored member hash: " + name)
|
||||
expected_logical = {"cargo/" + run + "/" + name for run in runs for name in RAW_FILES}
|
||||
expected_logical.update(spec["helper"] for spec in runs.values())
|
||||
expected_logical.update(helpers.values())
|
||||
for run, spec in runs.items():
|
||||
if "sourceProof" in spec:
|
||||
proof_spec = spec["sourceProof"]
|
||||
need(set(proof_spec) == {"commit", "pin", "comparator"}, run + ": exact source proof spec")
|
||||
need(isinstance(proof_spec["commit"], str) and re.fullmatch(r"[0-9a-f]{40}", proof_spec["commit"]), run + ": named full source commit")
|
||||
need(valid_pin(proof_spec["pin"]), run + ": source proof pin")
|
||||
need(isinstance(proof_spec["comparator"], str) and re.fullmatch(r"comparators/[0-9a-f]{64}\.py", proof_spec["comparator"]), run + ": comparator path")
|
||||
expected_logical.update({"cargo/" + run + "/source-proof.json", proof_spec["comparator"]})
|
||||
need(set(logical) == expected_logical, "exact logical raw/helper inventory")
|
||||
for name, destination in logical.items():
|
||||
if name.startswith("cargo/") and name.rsplit("/", 1)[1] in {"inputs.json", "inputs.zip"}:
|
||||
expected = "capsules/" + stored[destination]["sha256"] + PurePosixPath(name).suffix
|
||||
need(destination == expected, "input capsule mapping: " + name)
|
||||
else:
|
||||
need(destination == name, "only input maps/archives may be deduplicated: " + name)
|
||||
def raw(name):
|
||||
return read(logical[name])
|
||||
for name, helper in helpers.items():
|
||||
need(helper == "helpers/" + pin(raw(helper))["sha256"] + ".py", "named helper hash: " + name)
|
||||
seen_capsules = set()
|
||||
for run, spec in runs.items():
|
||||
prefix = "cargo/" + run + "/"
|
||||
start = parsed(raw(prefix + "started.json"))
|
||||
process = parsed(raw(prefix + "process.json"))
|
||||
result = parsed(raw(prefix + "result.json"))
|
||||
required_start = {"start", "command", "cwd", "head", "scope", "inputs", "archive",
|
||||
"inputCount", "environment", "helper", "cargo", "rustc"}
|
||||
need(required_start <= start.keys(), run + ": incomplete start receipt")
|
||||
need(all(result.get(key) == value for key, value in start.items()), run + ": start/result relationship")
|
||||
command = result["command"]
|
||||
need(isinstance(command, list) and command and command[0] == "cargo"
|
||||
and all(isinstance(arg, str) for arg in command), run + ": Cargo command")
|
||||
need(command == process["command"] == spec["command"], run + ": command relationship")
|
||||
need(result["head"] == spec["head"] and re.fullmatch(r"(?:[0-9a-f]{40}|[0-9a-f]{64})", result["head"]), run + ": HEAD")
|
||||
need(type(result["exitCode"]) is int and result["exitCode"] == spec["exitCode"], run + ": recorded exit")
|
||||
need(result["inputsUnchanged"] is True, run + ": changed inputs refused")
|
||||
need(type(result["seconds"]) in (int, float) and math.isfinite(result["seconds"])
|
||||
and result["seconds"] >= 0, run + ": duration")
|
||||
need(type(process["pid"]) is int and process["pid"] > 0, run + ": process identity")
|
||||
need(ordered_times(start["start"], process["observed"], result["finish"]), run + ": completed timestamp order")
|
||||
for field, filename in [("inputs", "inputs.json"), ("archive", "inputs.zip"), ("stdout", "stdout.log"), ("stderr", "stderr.log")]:
|
||||
need(result[field] == pin(raw(prefix + filename)), run + ": " + field + " pin")
|
||||
need(valid_pin(result["helper"]) and result["helper"] == pin(raw(spec["helper"])), run + ": helper pin")
|
||||
need(spec["helper"] == "helpers/" + result["helper"]["sha256"] + ".py", run + ": helper mapping")
|
||||
inputs = parsed(raw(prefix + "inputs.json"))
|
||||
need(isinstance(inputs, dict) and all(safe(name) for name in inputs), run + ": safe input inventory")
|
||||
need(type(result["inputCount"]) is int and len(inputs) == result["inputCount"] == spec["inputCount"], run + ": input counts")
|
||||
if "sourceProof" in spec:
|
||||
proof_spec = spec["sourceProof"]
|
||||
proof_bytes = raw(prefix + "source-proof.json")
|
||||
proof = parsed(proof_bytes)
|
||||
need(pin(proof_bytes) == proof_spec["pin"], run + ": source proof pinned bytes")
|
||||
need(proof["run"] == run and proof["commit"] == proof_spec["commit"], run + ": proof run/commit identity")
|
||||
need(proof["status"] == "PASS exact captured input inventory and Git blob bytes", run + ": source proof status")
|
||||
need(proof["inputCount"] == len(inputs) and proof["inputMap"] == result["inputs"], run + ": proof input relationship")
|
||||
need(proof["result"] == pin(raw(prefix + "result.json")), run + ": proof result relationship")
|
||||
need(ordered_times(result["finish"], proof["verified"]), run + ": proof time after closed gate")
|
||||
comparator = proof_spec["comparator"]
|
||||
need(valid_pin(proof["comparator"]) and pin(raw(comparator)) == proof["comparator"], run + ": comparator bytes")
|
||||
need(comparator == "comparators/" + proof["comparator"]["sha256"] + ".py", run + ": comparator identity")
|
||||
need(sum(name.startswith("crates/vendor/iced_widget/") for name in inputs) == 71, run + ": vendor count")
|
||||
capsule = (logical[prefix + "inputs.json"], logical[prefix + "inputs.zip"])
|
||||
if capsule not in seen_capsules:
|
||||
with zipfile.ZipFile(io.BytesIO(raw(prefix + "inputs.zip"))) as source:
|
||||
inventory(source, inputs)
|
||||
for name, expected in inputs.items():
|
||||
need(pin(source.read(name)) == expected, run + ": source hash " + name)
|
||||
seen_capsules.add(capsule)
|
||||
artifacts = []
|
||||
for line in raw(prefix + "stdout.log").decode("utf-8", errors="replace").splitlines():
|
||||
try:
|
||||
value = json.loads(line)
|
||||
except json.JSONDecodeError:
|
||||
continue
|
||||
if isinstance(value, dict) and value.get("reason") == "compiler-artifact" and value.get("executable"):
|
||||
artifacts.append(value)
|
||||
need(isinstance(result["artifacts"], list), run + ": artifact records")
|
||||
need(artifacts == [record["cargo"] for record in result["artifacts"]], run + ": Cargo JSON artifact relationship")
|
||||
for record in result["artifacts"]:
|
||||
need(set(record) == {"cargo", "readback"}
|
||||
and (record["readback"] is None or valid_pin(record["readback"])), run + ": artifact readback pin")
|
||||
print(run, "recorded exit", result["exitCode"], "inputs", len(inputs), "executable records", len(artifacts))
|
||||
return {"runs": len(runs), "recordedFailures": sum(spec["exitCode"] != 0 for spec in runs.values()),
|
||||
"logicalFiles": len(logical), "storedMembers": len(stored), "sourceCapsulePairs": len(seen_capsules),
|
||||
"captureHelpers": helpers, "sourceProofs": sum("sourceProof" in spec for spec in runs.values())}
|
||||
|
||||
|
||||
def verify_package(root):
|
||||
files = parsed((root / "files.json").read_bytes())
|
||||
need(set(files) == OUTER_FILES, "outer file inventory")
|
||||
for name, expected in files.items():
|
||||
need(valid_pin(expected) and pin((root / name).read_bytes()) == expected, "outer hash: " + name)
|
||||
manifest = parsed((root / "manifest.json").read_bytes())
|
||||
with zipfile.ZipFile(root / "evidence.zip") as archive:
|
||||
inventory(archive, manifest["members"])
|
||||
return verify_data(manifest, archive.read)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("package", nargs="?", type=Path, default=Path(__file__).resolve().parent)
|
||||
args = parser.parse_args()
|
||||
print("PASS offline consistency:", verify_package(args.package))
|
||||
print("Historical receipts only; no source/binary execution or native acceptance claim.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,26 @@
|
||||
# Preserved independent review records
|
||||
|
||||
[reviews.zip](reviews.zip) contains six exact historical Markdown records,
|
||||
pinned by [members.json](members.json). Their original context was
|
||||
`.local/allocation-group-design/` in the reviewed checkout. Relative links and
|
||||
line references inside this historical archive retain that context and reviewed
|
||||
source version; they are not links to an installed peer workspace.
|
||||
|
||||
| Record | Scope |
|
||||
| --- | --- |
|
||||
| critique.md | Initial combined assignment/Arrange proposal criticism |
|
||||
| fresh-policy-critique.md | Independent policy alternatives and falsifiers |
|
||||
| experiment/v2-review.md | Four-family experiment; SA port sizing oracle defect |
|
||||
| selection-boundary.md | Exact typed App selection versus pure placement API |
|
||||
| input-boundaries.md | Pending click, irreversible threshold and input integration obligations |
|
||||
| arrange-planner-review.md | Fresh pure-planner review plus R1/R2 test-disposition addendum |
|
||||
|
||||
The [accepted contract](../../allocation-arrange-amendment-20260923.md) and
|
||||
[result report](../../allocation-arrange-planner-20260923.md) are authoritative for
|
||||
current decisions and acceptance. Historical recommendations or proposed APIs
|
||||
inside the archive do not supersede them. Root verified reported execution
|
||||
separately; review authors did not independently run Cargo or native workflows.
|
||||
|
||||
The report records remaining P3 coverage suggestions and App/native gaps.
|
||||
The archive preserves earlier findings even when the dated addendum addresses
|
||||
them. [files.json](files.json) pins this index, the archive and its member map.
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"README.md": {
|
||||
"bytes": 1576,
|
||||
"sha256": "b25dc1db4a8a46f5f41381426a237f1a21f21f8b18c0bbfc8590b6f91804d03b"
|
||||
},
|
||||
"reviews.zip": {
|
||||
"bytes": 28248,
|
||||
"sha256": "d9202f0c6b82ad383de3b4e9e84bb0457f62ae53f1511c458294b0593753e2f1"
|
||||
},
|
||||
"members.json": {
|
||||
"bytes": 831,
|
||||
"sha256": "2edee904da60ca409192a6152952b556d61bcb36cddcfcfce29fd65476a4fba7"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"critique.md": {
|
||||
"bytes": 8955,
|
||||
"sha256": "a69c27b472f27e06567a216836b42c1593956f23616a6d12ef6ec61c1cf29bdb"
|
||||
},
|
||||
"fresh-policy-critique.md": {
|
||||
"bytes": 15227,
|
||||
"sha256": "d9ce5c5e6b3f61c8f5933424e178a476f65e262a8990380021c461fd7bcbe38b"
|
||||
},
|
||||
"experiment/v2-review.md": {
|
||||
"bytes": 5901,
|
||||
"sha256": "46439cdf44cef6d95b8b45df1ba93fd27ca9b78c9470e4c5b9e166ce3082a1f2"
|
||||
},
|
||||
"selection-boundary.md": {
|
||||
"bytes": 6420,
|
||||
"sha256": "f7971131bac65cde48810abb629695a5a3d0a0aa5b8d115b5fa141b8c3fe5988"
|
||||
},
|
||||
"input-boundaries.md": {
|
||||
"bytes": 16200,
|
||||
"sha256": "81a2b55d3dde1f658bf10811d06fa0bf1759afc90aa616a376a754cec5af6d22"
|
||||
},
|
||||
"arrange-planner-review.md": {
|
||||
"bytes": 13461,
|
||||
"sha256": "6171cd269a261ebf255fd75b04a155b78cdb359940b164557a3bc2409b7df3b8"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,136 @@
|
||||
# Allocation Arrange policy and pure planner — 2026-09-23
|
||||
|
||||
Codex-9e8r6t contribution to [issue 29](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/29), above Process delivery `6d99aacab8ca1a91c857a2179baa14d80a2901e9`.
|
||||
**Pure planner verified; App integration and native acceptance remain open.**
|
||||
This is not a release or full Allocation/multiselect completion claim.
|
||||
|
||||
## Result and decision
|
||||
|
||||
The [accepted amendment](allocation-arrange-amendment-20260923.md) defines explicit
|
||||
Arrange for one or more work/performer placements. It preserves engineering
|
||||
records and moves one union: semantic descendants of explicitly selected work
|
||||
plus accepted visual descendants of explicitly selected performers. It does not
|
||||
acquire incidental semantic parents or siblings. Ordinary assignment retains its
|
||||
existing per-root responsibility and coherence rules.
|
||||
|
||||
The experiment compared strict refusal, visible-selected-only movement and this
|
||||
combined footprint. Strict refusal discarded valid semantics-preserving layouts;
|
||||
visible-only movement omitted hidden/semantic descendants. Actual OA/SA examples
|
||||
support the bounded union policy, subject to complete geometry checks. There is
|
||||
no automatic packing, convergence, semantic reparenting or target unfolding.
|
||||
|
||||
Both visible and required diagnostic scenes check **all** unrelated card pairs.
|
||||
An unselected performer's derived enclosure can grow into an obstacle even when
|
||||
none of the moved cards touches it. Diagnostics unfold affected placements and
|
||||
their required visual ancestors; unrelated stationary folded interiors remain
|
||||
outside that domain. The experiment explicitly distinguishes this policy from
|
||||
universal unfolding. Future expansion can reveal overlap.
|
||||
|
||||
At source **9b83f7ca0dcd34056765b9399863a21da72c3a9f**,
|
||||
[`arrange.rs`](../crates/oa-desktop/src/allocation_drag/arrange.rs) implements
|
||||
immutable capture/place/finish, exact original placement identities, one snapped
|
||||
anchor delta, route translation using actual accepted endpoint owners, combined
|
||||
projection, every selected header, stale/tamper rejection and an exact final
|
||||
Project comparison. Motion reuses the semantic index and captured footprint;
|
||||
it does not clone/validate a Project per pointer position. Pairwise collision
|
||||
cost remains real; no large-scene latency benchmark is claimed.
|
||||
|
||||
The planner's ID map is deliberately not an input capability. App must validate
|
||||
the entire original typed selection before conversion, retaining its exact
|
||||
snapshot/generation and clean-owner lifetime. The new module is not yet connected
|
||||
to App; its temporary dead-code annotation states that boundary. The only change
|
||||
to singleton capture extracts its already-validated fact collector; ordinary
|
||||
singleton policy is unchanged.
|
||||
|
||||
## Exact verification
|
||||
|
||||
All twelve closed runs are preserved in the [portable evidence](allocation-arrange-evidence-20260923/checks/README.md).
|
||||
Every run reports unchanged captured inputs, including all 71 patched Iced files.
|
||||
Recorded compile failures remain failures. Historical HEAD alone does not identify
|
||||
uncommitted captured inputs; named source proofs compare the complete relevant
|
||||
Git inventory and every blob byte with the captured map.
|
||||
|
||||
| Gates | Observed result | Exact source |
|
||||
| --- | --- | --- |
|
||||
| experiment-1 | 2 OA experiment tests pass | 743 blobs at `3a7923b96d671041cbc747a614cbd0fad6b6b3d3` |
|
||||
| experiment-2 | Compile failure: imported module resolved desktop-wide tests | Captured capsule retained; no named-commit proof |
|
||||
| experiment-3 | Four OA/SA experiment families pass, 57 filtered | 744 blobs at `8dbbaf262e3b8d26a32d6c30f0cc5f963fab47a0` |
|
||||
| planner-document-1 | All 61 planner/Document module tests pass | Same `8dbbaf2` bytes |
|
||||
| probe-lint-1 / format-1 | Strict scoped Clippy and workspace format pass | Same `8dbbaf2` bytes |
|
||||
| arrange-planner-1 / -2 | Compile failures: missing explicit module path, then test temporary-array borrow | Both exact capsules retained |
|
||||
| arrange-planner-3 | 67 tests pass, 2.44s | Earlier captured planner/tests; not labelled as `8dbbaf2` |
|
||||
| arrange-planner-4 | **70 tests pass**, 2.77s | 746 blobs at `9b83f7ca0dcd34056765b9399863a21da72c3a9f` |
|
||||
| arrange-lint-1 / arrange-format-1 | Strict scoped Clippy and workspace format pass | Same `9b83f7c` bytes |
|
||||
|
||||
The final input-map SHA-256 is
|
||||
`c8192fd84fba63fa576975e9fd44f0fa2d6c8ed2e6b5ada3fd4bee076d36f686`.
|
||||
The 70 include nine new Arrange test families and the existing 61 module tests.
|
||||
Literal full-Project oracles check engineering records, sizes/folds, other views,
|
||||
internal and one-ended saved routes. Actual Document execution checks compiled
|
||||
source, reopen and one exact Undo/Redo. Further cases exercise either selected
|
||||
anchor, parent/child deduplication, role-only work, unplaced leaves, simultaneous
|
||||
vacated-space movement, preexisting-overlap preservation versus growth, hidden
|
||||
collision versus unselected enclosure growth, no-op, stale/tampered results and
|
||||
all selected headers. These are pure/source checks, not native gesture evidence.
|
||||
|
||||
The first experiment's untouched fresh-Document assertion was not atomic refusal
|
||||
evidence; the successor removed that overstatement. Independent review also
|
||||
corrected SA oracle literals before execution: FunctionalExchange auto-ports
|
||||
raise projected work height from OA 94 to SA 132, enclosure height 218 to 256,
|
||||
and the hidden overlap area 13696 to 20116. Production sizing was not changed to
|
||||
fit an oracle.
|
||||
|
||||
## Independent review and remaining checks
|
||||
|
||||
[Preserved reviews](allocation-arrange-evidence-20260923/reviews/README.md) record
|
||||
policy criticism, the SA oracle finding, the selection boundary and fresh planner
|
||||
review. No concrete planner defect was found. Review R1/R2 led to independent
|
||||
collision-cause discriminators, a singleton-refuses/combined-passes vacated-space
|
||||
case, and unchanged-overlap versus enlargement controls. The final planner
|
||||
production bytes are unchanged from the reviewed 67-test capture; only
|
||||
`arrange_tests.rs` differs in the 70-test capture.
|
||||
|
||||
Deeper nested folded ancestry, explicit endpoint attachment fixtures and broader
|
||||
tamper/non-grid cases remain protective P3 coverage suggestions, not reproduced
|
||||
defects or completed checks. App must retain minimum readable text scale; the
|
||||
pure planner validates world-space header containment and finite positive zoom.
|
||||
|
||||
App integration must still prove exact whole typed-set admission, deferred
|
||||
selected-member click collapse, an irreversible drag threshold, one-shot Arrange
|
||||
on both performer/work anchors, dirty/source-failure preservation, stale selection
|
||||
generation, cancellation, frozen geometry and truthful preview/counts. Ordinary
|
||||
work-only group assignment needs its own combined semantic candidate. OA/SA native
|
||||
workflows, actual Save/reopen, Scenario group operations and aggregate deletion
|
||||
remain open. Existing Process routing overlap is not solved here. Linux/WSL
|
||||
verification remains user-paused.
|
||||
|
||||
## Reproduction and portable records
|
||||
|
||||
Verified on Windows x86_64 gnullvm, Rust/Cargo 1.98.1, LLVM-MinGW20260826,
|
||||
one build job and incremental compilation disabled. Initialize the documented
|
||||
project toolchain/DLL environment before invoking Cargo. From the named source:
|
||||
|
||||
```powershell
|
||||
$env:CARGO_BUILD_JOBS='1'
|
||||
$env:CARGO_INCREMENTAL='0'
|
||||
cargo test -p oa-desktop --example allocation_policy_probe --message-format=json -- --test-threads=1
|
||||
cargo clippy -p oa-desktop --example allocation_policy_probe --tests --message-format=json -- -D warnings
|
||||
cargo fmt --all -- --check
|
||||
python -B harness/allocation-arrange-evidence-20260923/checks/verify.py
|
||||
```
|
||||
|
||||
The focused example imports the actual planner and Document modules. It does not
|
||||
replace desktop/App/native acceptance. The initial full desktop experiment
|
||||
reported 30m42s compile time; the focused successor reported 7.11s. This useful
|
||||
iteration improvement is not a controlled benchmark: target graphs, warm artifacts
|
||||
and machine state differ.
|
||||
|
||||
The package retains twelve runs, three compile failures, eight named source
|
||||
proofs, 95 logical files in 85 stored members and seven deduplicated source
|
||||
capsule pairs. Offline verification checks exact inventories, pins, streams,
|
||||
receipts, source capsule contents and proof relationships; it does not execute
|
||||
archived code, independently authenticate logs or repeat Git comparisons.
|
||||
The packager's corruption checks rejected eleven changed relationships and an
|
||||
attempt to overwrite an existing output. Root verified all eleven exact staged
|
||||
evidence files in a fresh export: the portable checks verifier and every review
|
||||
archive/member pin passed without consulting working-copy evidence bytes.
|
||||
@@ -80,6 +80,11 @@ members; explain the refusal and offer the existing Arrange-only operation.
|
||||
Explicit Arrange-only always preserves every allocation record. Destination
|
||||
feedback and hit geometry remain stable throughout the gesture.
|
||||
|
||||
The [explicit Arrange amendment](allocation-arrange-amendment-20260923.md) defines
|
||||
the bounded one-or-more work/performer footprint and diagnostic collision domain.
|
||||
Its [pure planner evidence](allocation-arrange-planner-20260923.md) does not yet
|
||||
establish App/native group input acceptance or ordinary group assignment.
|
||||
|
||||
## Related group actions
|
||||
|
||||
Move/reorder and removal are the initial useful operation families. Saved-view
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# Allocation drag contract v2 — 2026-09-11
|
||||
|
||||
**2026-09-23 explicit Arrange amendment:**
|
||||
[the accepted bounded policy](allocation-arrange-amendment-20260923.md) supersedes
|
||||
the mixed/coherence pre-veto only for explicit Arrange, with a declared combined
|
||||
footprint and geometry gate. [Pure planner verification](allocation-arrange-planner-20260923.md)
|
||||
is complete within its recorded scope; App/native integration remains pending.
|
||||
Ordinary assignment and all other v2 lifetime/source rules remain binding.
|
||||
|
||||
Codex-956atf `/root/capella_process_gap`. Implementation-ready proposal for root ratification of [issue 3](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/3). The [original design](release-activity-allocation-drag-design-20260911.md) and [independent review](release-activity-allocation-drag-review-20260911.md) remain immutable. Root accepted all five review corrections; this document resolves them without claiming implementation, issue closure or full-goal completion.
|
||||
|
||||
**2026-09-12 presentation amendment:** the [destination feedback decision](release-allocation-feedback-decision-20260912.md) supersedes references below requiring a duplicate target-name label at its frozen canvas position. Target hit regions and outlines remain frozen; destination identity moves to a dedicated stable toolbar slot. This prevents label occlusion without making ordinary collapsed-target drops unreachable. All semantic, exact-placement and lifetime rules remain binding.
|
||||
|
||||
Reference in New Issue
Block a user