chore: gate multi-repo remote rewrite on $http_proxy (#63 round 2)#92
Merged
Conversation
Propagation from cycles-spring-boot-starter#66.
amavashev
added a commit
that referenced
this pull request
May 13, 2026
…ype discriminator, commit/release reservation_id requirement, stale prose) Three review findings on PR #90 round 3. All addressed, all empirically verified before commit. Same rigor protocol as round 2 (negative tests for every new constraint). 1. MEDIUM — schema-only validators accepted artifact_type / payload key mismatches. The previous `EvidencePayload.oneOf` enforced that `payload` had exactly one of {decide, reserve, commit, release, error}, but did NOT tie that key to `artifact_type`. So an envelope with `artifact_type: reserve` and `payload.error` validated at the schema layer. The custom `verify.py` catches this, but any consumer using JSON Schema alone (an APS verifier, an offline auditor, a generic gateway) would silently accept the impossible envelope. Empirically reproduced: fixture 02 with payload swapped to fixture 11's `payload.error` → previous schema accepted it. Fix: top-level `allOf` of five `if`/`then` rules on `CyclesEvidence`, one per artifact_type, requiring `payload` to contain the matching key. The pairing now lives in the schema, not just in the custom verifier. Verified via cross-product: all 5 × 5 = 25 (artifact_type X, payload Y) combinations checked; 5 matching pairs accepted, 20 mismatch pairs rejected. 2. MEDIUM — `ErrorPayload.reservation_id` was optional even for commit/release endpoints, breaking authorization chain linkage. The `reservation_id` is the URL path argument of `POST /v1/reservations/{reservation_id}/{commit,release}`. For successful evidence (`CommitPayload`, `ReleasePayload`), `reservation_id` is REQUIRED — that's the whole point of the hoist discussed in the #92 round-4 review. But `ErrorPayload` left it optional unconditionally, so a 4xx/5xx error on those same paths could ship without the linkage. Empirically reproduced: error envelope with `endpoint: POST /v1/reservations/{reservation_id}/commit` and a valid `CommitRequestMirror`-shaped body but no `reservation_id` → previous schema accepted it. Fix: add a 5th branch to `ErrorPayload.allOf` requiring `reservation_id` when `endpoint` is the commit or release path. Endpoints with no path-arg reservation_id (`POST /v1/decisions`, `POST /v1/reservations`) are unaffected. Verified: commit/release endpoint without reservation_id → REJECTED; commit endpoint WITH reservation_id → VALID; non-commit/release endpoints without reservation_id remain VALID. Prose: ErrorPayload description updated to call out the conditional "required when endpoint is commit/release" rule, citing the same chain-completeness rationale as CommitPayload/ReleasePayload. 3. LOW — stale prose said "four properties" / "other three" but `error` is now a 5th branch. `EvidencePayload.description` updated to "five properties" / "other four", with a new sentence noting that the artifact_type ↔ payload-key pairing is enforced at the top-level CyclesEvidence schema via `allOf`/`if`/`then` (so schema-only validators reject mismatches without needing the custom verifier). Byte stability: no fixture canonical bytes change in this commit (only spec yaml edited; generator untouched). All 11 evidence_ids and signatures are byte-identical to the prior commit. Validation summary: - python verify.py: 11/11 verified - JSON Schema validate all 11 fixtures against the tightened spec: 11/11 valid - F1 cross-product matrix: 20/20 artifact_type/payload mismatches rejected (5 matching pairs remain valid) - F2 negatives: commit-endpoint and release-endpoint ErrorPayload without reservation_id both REJECTED - F2 positive: commit-endpoint ErrorPayload WITH reservation_id VALID - All prior regression negatives still trip (non-dry DENY, commit-body under reserve endpoint, ttl_ms below canonical min) - npx spectral lint drafts/cycles-evidence-v0.1.yaml --fail-severity=error: 0 errors, 3 expected warnings (unchanged set)
Merged
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Propagation from cycles-spring-boot-starter#66. runcycles/.github#63 — Part 2 of session-start-global-deny.sh now exits 0 unless
$http_proxyis set, so the multi-repo remote rewrite is safe-by-default on vanilla dev machines.