You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Integrity history: reject explicitly malformed v1/v2 carrier arrays instead of treating them as empty #83
Revalidated src/devostasis/revision_history.py::_carried_records at cumulative PR #81/#75 head a4761daa9fa87026ea106a3d722e7299b3de3b8b on 2026-10-22. The current-inventory and exact-attempt-coverage repairs are already present and are not being reported again.
The remaining carrier-reader paths use:
parents_from_groups(record.get("parent_groups") or [], where)
unresolved=record.get("unresolved") or []
[parent_from_current(p, where) forpinrecord.get("parents") or []]
Consequently, explicit null, false, 0, "" and {} can be normalized to an empty collection before validation. The v1 parents path also lacks an explicit list-type check. This conflates absent optional fields with corrupt persisted evidence.
Public reproduction
Call _carried_records with a dictionary containing lineage=LINEAGE, records=[{"revision":"r1", "committed_at":"2026-10-01T00:00:00Z", "parent_groups":false}]. Instead of raising HistoryShapeError, the present implementation treats the parent set as empty. Repeat for the other false-like values; independently mutate unresolved under v2 and parents under REPLAYABLE_LINEAGE (v1). Use ordinary empty arrays and omitted optional keys as positive compatibility controls.
A malformed carrier must not silently become evidence of no decisive executions or complete favorable history. This is structural admission, not a new threshold, window or history-state interpretation. The broad current-inventory findings in #38/#57 do not explicitly track this remaining reader bug.
Repair scope
Use record.get(key, []) only where absence is already allowed, then validate the actual supplied value. Validate v1 parents as a list before iterating. Keep unknown lineage handling, valid empty arrays, supported historical replay and all accepted current/history rules unchanged. Do not relax tests or recompute historical artifacts under a new rule to hide incompatibility.
Acceptance
Parameterized tests reject None, False, 0, empty string and empty object for each of the three arrays, with HistoryShapeError rather than unrelated exceptions.
Omitted optional keys and real empty arrays preserve documented compatibility; valid failing/passing parent evidence still reconstructs identically.
Public reconciliation/evaluator coverage confirms malformed history produces a diagnostic/unknown result, not a silently clean result.
Full repository tests and four-generation bundle replay run at the exact fixing head; historical valid examples continue to verify.
The fix is propagated consistently through the prepared release candidates that carry this reader, with independent review before release.
Prior local patch packages contain a minimal candidate and limited probes; these are not a substitute for a real checkout run. Search across open and closed issues and the current #81 discussion found no dedicated parent_groups finding. Related: #57, #81, #75.
Implementation-ready source repair for the existing release chain
Base checked: a4761daa9fa87026ea106a3d722e7299b3de3b8b; src/devostasis/revision_history.py blob e7c871965c2f783ae6991d6d2c6d20596e81daa7. The same blob was read at the current #57/#59/#64/#69 heads. This is a proposed patch, not a committed fix or closed issue.
--- a/src/devostasis/revision_history.py+++ b/src/devostasis/revision_history.py@@ -266,15 +266,18 @@
seen.add(record["revision"])
timeutil.parse_ts(record["committed_at"])
if lineage == LINEAGE:
- parents = parents_from_groups(record.get("parent_groups") or [], where)- unresolved = record.get("unresolved") or []+ parents = parents_from_groups(record.get("parent_groups", []), where)+ unresolved = record.get("unresolved", [])
if not isinstance(unresolved, list) or not all(isinstance(reason, str) for reason in unresolved):
raise HistoryShapeError(f"{where}: unresolved is not a list of reasons")
records.append(union_record(record["revision"], record["committed_at"], merge_parents(parents)[0], unresolved))
elif lineage == REPLAYABLE_LINEAGE:
# HIST-13: replayed from the canonical attempts the older record kept,
# never copied from the state it derived under the older semantics.
- parents = [parent_from_current(p, where) for p in record.get("parents") or []]+ previous_parents = record.get("parents", [])+ if not isinstance(previous_parents, list):+ raise HistoryShapeError(f"{where}: parents is not a list")+ parents = [parent_from_current(p, where) for p in previous_parents]
records.append(union_record(record["revision"], record["committed_at"], merge_parents(parents)[0], []))
else:
# HIST-15: no replay and no accepted migration from this lineage; the
15 malformed cases + 6 omission/empty compatibility cases + 1 evaluator-boundary case. Full checkout execution, store-chain replay and full pytest remain required; syntax/context checks alone are not acceptance. Keep the defect open until the fix is committed, verified and independently reviewed.
Independent exact-head reconciliation gate for #83 (2026-10-23)
Inspected at PR #81 head a4761daa9fa87026ea106a3d722e7299b3de3b8b: src/devostasis/revision_history.py blob e7c871965c2f783ae6991d6d2c6d20596e81daa7, src/devostasis/vitals/integrity.py blob da6b6e91af0dfb6d75ad1f853b8bf8465f0e105d, and existing tests/test_revision_history.py.
Narrow finding: the prior candidate patch is sufficient at the parser boundary; the downstream fail-closed handling already exists. reconcile() catches HistoryShapeError, records SOURCE_MALFORMED and a REVISION_HISTORY_CARRY_MALFORMED:... problem. integrity._evaluate_revisions() sees reconciled.problems and returns _unknown(...), whose band=None and evaluation_status=UNKNOWN. No independent alteration of the Vital bands or history semantics is justified.
Strengthen the pending evaluator regression beyond asserting only that a diagnostic exists. Use a fully populated positive current sample (four recent PASS revisions) to prove a malformed predecessor cannot still produce a favorable exact band. Parameterize all three offending arrays and five explicit false-like invalid values:
This adds the specific 15 evaluator-level no-false-success obligations (not just 15 parser exceptions) while reusing the existing test helpers/imports shown in the earlier comment. Keep its six allowed omission/empty-array controls, plus valid v1/v2 historical replay. It does not reopen current-series or attempt-coverage changes.
Verification status: exact-head static control-flow inspection PASS; proposed 15 new evaluator cases NOT_RUN; full pytest, four-generation bundle replay and hosted CI NOT_PASS/NOT_RUN. Current PR #81 CI runs remain action_required. Do not close #83 or merge #81/#75 on this analysis alone.
Executed isolated red/green verification for #83 (2026-10-23)
Re-read the exact _carried_records implementation from PR #81 head a4761daa9fa87026ea106a3d722e7299b3de3b8b, src/devostasis/revision_history.py blob e7c871965c2f783ae6991d6d2c6d20596e81daa7. This is a verification follow-up to the existing concrete patch in comment 6334241779, not a new semantic contract or new Issue.
Executed a standalone Python 3.13.5 harness containing the exact _carried_records body as read from that head, plus narrow helper stand-ins for type/parent semantics.
Before fix: 15/15 explicit malformed array values (None, False, 0, "", {} across v2 parent_groups, v2 unresolved, v1 parents) silently accepted as empty evidence.
After the minimal three-site fix: 15/15 rejected with HistoryShapeError.
Patch context:git apply --check and application PASS on a representative reconstructed function excerpt, not a checkout of the full repository.
Real-repo regression additions prepared: 15 parser rejection instances, 6 omission/empty compatibility controls, 15 evaluator no-false-success instances with four current PASS revisions (36 pytest cases total). Their syntax was compiled but those full repository tests have NOT_RUN.
Exact scope: Replace record.get("parent_groups") or [] and record.get("unresolved") or [] with record.get(key, []); for v1, first type-check previous_parents = record.get("parents", []) as a list before mapping parent_from_current. No new Integrity rule/version, band, window or history state is proposed.
Acceptance still required before release: apply through a focused feature PR into the active release branch; execute actual pytest, historical four-generation bundle replay and hosted checks at the new exact head; obtain an independent later-run review. Current #81 hosted Actions runs still report action_required (NOT_PASS). This comment is executed parser-boundary evidence only; it does not claim that upstream code changed.
Working copy patch SHA-256: ebb47dba90a122faf666d324823c205362118a1a47e10c67e265b44e55095266.
#83 handoff refinement: preserve failing evidence on both historical carrier lineages (2026-10-24)
Reviewed exact base remains PR #81a4761daa9fa87026ea106a3d722e7299b3de3b8b, src/devostasis/revision_history.py blob e7c871965c2f783ae6991d6d2c6d20596e81daa7; existing implementation patch is in comment 6334241779. No repository source write or new PR is claimed.
I prepared an exact-blob-guarded offline patch applicator plus a 38-instance pytest regression module. This extends the previously prepared 36 cases with two explicit positive controls: a real VERIFY_FAIL attempt must continue to replay as FAILURE_OBSERVED / VERIFY_FAIL for both the v2 parent_groups carrier and the v1 parents carrier. This ensures that hardening malformed-array admission cannot discard previously established failures.
The 38 instances are: 15 explicit malformed-array parser rejections, 15 public Integrity no-false-success checks with four current passing revisions, 6 omission/empty-array compatibility checks, and 2 v1/v2 failing-parent replay checks. The script checks the full source blob hash, requires a non-master feature checkout, and refuses missing/changed source occurrences. Its three substitutions and reapplication refusal were verified against a representative exact source-line excerpt; Python compilation PASS. Real repository pytest, historical bundle replay, and hosted CI at a fixing HEAD are NOT_RUN.
Acceptance still requires a maintainer with push to apply the existing three-site patch on a feature branch targeting release/0.6.0, add all the above tests, run the actual full suite and historical bundle checks, and obtain later independent review. The earlier GitHub-side runner remains action_required (NOT_PASS). Do not close #83 on handoff evidence alone.
Safety correction (2026-10-24): patch applicator must refuse release branches
The handoff's offlineapply_carrier_fix.py formerly rejected only master and detached HEAD. That inadvertently permitted direct source writes on release/0.6.0, contrary to the repository's feature/fix PR discipline. This corrects the handoff tool, not Devostasis production code.
After git branch --show-current, check:
current_branch=branch.stdout.strip()
if (branch.returncode!=0ornotcurrent_branchorcurrent_branchin {"master", "main"}
orcurrent_branch.startswith("release/")):
raiseRuntimeError("Use a focused feature/fix branch; refuse master/main/release/detached HEAD")
head=subprocess.run(["git", "rev-parse", "HEAD"], capture_output=True, text=True, check=False)
ifhead.returncode!=0orhead.stdout.strip() !="a4761daa9fa87026ea106a3d722e7299b3de3b8b":
raiseRuntimeError("The checkout is not the reviewed PR #81 base; re-review before patching")
Verified the amended applicator locally in temporary Git repositories: 3/3 refusal controls PASS (master, release/0.6.0, unrelated feature/issue-83 base); Python compilation PASS. The old three-source-line fix and 38 proposed regression cases remain unchanged. NOT_RUN: real Devostasis checkout/pytest, 4-generation replay, wheel CI; these must still be run after a legitimate feature PR. No repository commit/PR/merge is claimed.
Base: PR #81a4761daa9fa87026ea106a3d722e7299b3de3b8b; src/devostasis/revision_history.py blob e7c871965c2f783ae6991d6d2c6d20596e81daa7. This is adjacent to, but not fixed by, the existing three-site _carried_records candidate.
In carried_observation(), the fallback for a pre-carrier (0.1.x) predecessor reads its ci.revision_verdicts_14d observation as:
Thus a predecessor whose series claims AVAILABLE or PARTIAL, but explicitly contains value: null, false, 0, "", or {}, is silently converted to an empty, AVAILABLE v1 carrier (lineage=REPLAYABLE_LINEAGE, records=[]). The downstream _carried_records() cannot reject the original bad shape because it has already been erased. This defeats the same fail-closed admission objective for the legacy replay entry path.
Executed bounded reproduction: copied the source's carried_observation, _in_window, and _replay_source bodies into an isolated Python 3.13 harness with minimal observation/time stand-ins. The existing code normalized 10/10 invalid inputs (five values × statuses AVAILABLE/PARTIAL) to records=[]. A candidate change preserved the invalid types in 10/10 cases; valid empty-array and a v1 record containing an observed VERIFY_FAIL remained intact. This is not a full checkout/integration pytest and does not prove every downstream behavior.
Minimal independent structural repair suggestion (preserve malformed AVAILABLE/PARTIAL values for the already-present reconcile() -> _carried_records() -> HistoryShapeError -> SOURCE_MALFORMED path):
The separate handling of non-AVAILABLE/PARTIAL statuses is unchanged here; whether it needs a stricter historical contract is out of scope. No Vital threshold/band rule or lineage identifier is changed.
Acceptance addition to #83: exercise malformed AVAILABLE/PARTIAL legacy predecessor series (all five values) through the actual bundle/reconciliation/Integrity evaluation, assert REVISION_HISTORY_CARRY_MALFORMED and UNKNOWN rather than an apparently empty historical carrier; retain genuinely empty arrays and v1 failing-parent replay; run full tests/four-generation historical replay at the eventual fixing head.
Write boundary: no source commit/PR/merge or full-repo test is claimed; upstream PR #81 remains blocked and must be independently reviewed after a fixing commit.
Prepared a single offline, exact-source-blobs guarded repair covering both existing carrier-reader admission (the 3 changes in comment 6334241779) and the legacy pre-carrier v1 replay normalization described above. This is a prepared local handoff, NOT an upstream commit or PR. Do not treat it as release acceptance.
Fourth production-site replacement in carried_observation (relative to exact PR #81 HEAD a4761daa9fa87026ea106a3d722e7299b3de3b8b, blob e7c871965c2f783ae6991d6d2c6d20596e81daa7):
- records = series.get("value") if series.get("status") in (AVAILABLE, PARTIAL) and isinstance(series.get("value"), list) else []- replayable = [_replay_source(record) for record in _in_window(records, observed_at)]+ records = series.get("value") if series.get("status") in (AVAILABLE, PARTIAL) else []+ windowed_records = _in_window(records, observed_at)+ replayable = ([_replay_source(record) for record in windowed_records]+ if isinstance(windowed_records, list) else windowed_records)
New real-repository regression design (tests/test_legacy_history_carrier_admission.py): for each AVAILABLE/PARTIAL predecessor with value in [None, False, 0, "", {}], verify carried_observation preserves the invalid value (10 cases) and integrity.evaluate emits REVISION_HISTORY_CARRY_MALFORMED with UNKNOWN and no band even against four currently passing revisions (10 cases). Confirm actual [] remains compatible for both statuses (2 cases), and a valid legacy VERIFY_FAIL parent remains failing (1 case). Combined with the previously prepared 38 cases, this is 61 proposed pytest instances.
Executed local checks: all four exact-source-line substitutions applied/compiled in a representative code excerpt; reapplication was refused; a source-copied legacy stand-in preserved 10/10 malformed values instead of silently emptying them and preserved 2/2 genuine empty arrays; all prepared Python modules compile. NOT_RUN: those 61 actual repository pytest cases, full pytest, historical four-generation replay, wheel/sample verification and upstream CI (the two a4761daa Actions runs are still action_required, NOT_PASS).
The offline applicator refuses protected/detached branches, wrong HEAD/blob, unclean trees and overwrite of existing tests; keep its files outside the checkout and apply only on a focused fix/ or feature/ branch. Before declaring #83 resolved: commit the four-site change + tests into a focused PR targeting release/0.6.0, run full and historical tests at the fixing HEAD, and obtain independent later-run review.
Exact source: PR #81 HEAD a4761da; src/devostasis/revision_history.py blob e7c871965c2f783ae6991d6d2c6d20596e81daa7. This is an implementation admission error under the existing durable-history contract, not a new Vital policy.
In _carried_records(), the REPLAYABLE_LINEAGE (0.1.x) branch computes merge_parents(parents)[0], discarding the second return value (PARENT_KIND_CONFLICT:). union_record(..., []) then treats the contradiction as if it never existed.
Minimal malformed v1 carrier: one revision has two parent objects, both with parent_id = "p", current_attempt = 1, and attempts_observed = [{"attempt":1,"state":"VERIFY_PASS"}]. The first object has kind = "github_actions_workflow_run"; the second kind = "github_actions_check_suite". With the same evidence but different input order:
Check suite first: UNKNOWN_HISTORY, history_complete = False.
Preserving merge_parents' conflict list as unresolved gives UNKNOWN_HISTORY for both orders and preserves VERIFY_FAIL as an absorbing result.
Minimal source repair, alongside the existing four-site #83 candidate:
# after previous_parents is list-validated and mapped with parent_from_current
merged, conflicts = merge_parents(parents)
records.append(union_record(record["revision"], record["committed_at"], merged, conflicts))
The downstream reconcile() already propagates conflicts as unresolved; LINEAGE v2 already refuses duplicated parent IDs across groups. This change aligns v1 replay with existing rules rather than tuning semantics.
Executed verification: isolated Python 3.13.5 source-faithful helper reproduction with 7/7 assertions PASS, including both input orders, distinct/same-kind controls, a retained conflict and an absorbing failure. This is NOT a real package pytest. Prepared a fifth exact-context replacement and four additional pytest scenarios, bringing the prior 61 prepared cases to 65 proposed cases. Local preflight of all 5 substitutions and patched-fragment compilation PASS; installer and test modules parse. Full checkout, 65 actual pytest instances, historical bundle replay, hosted CI and fixing PR are NOT_RUN/NOT_DONE. This issue comment does not land code; account andy-zen-dev has pull=true, push=false.
Acceptance addition: a conflicting v1 parent kind must never become favorable solely because the Actions-kind entry appears first. Preserve failure absorption and valid same-kind behavior; use a focused feature PR targeting release/0.6.0 and a later independent exact-head review. Contract question #87 is separate.
2026-10-24 — #83 downstream regression: the v1 parent-kind conflict can still disappear
Exact re-read: PR #81a4761daa9fa87026ea106a3d722e7299b3de3b8b (open, base release/0.6.0), src/devostasis/revision_history.py blob e7c871965c2f783ae6991d6d2c6d20596e81daa7. This corrects my earlier #83 comment #6379109245: keeping merge_parents(...)[1] as unresolved during the v1 parser step is necessary but not sufficient.
Proof by source transition: a 0.1.x carrier has two parents with the same parent_id="p", each with attempt 1 = VERIFY_PASS; one is github_actions_workflow_run, the other github_actions_check_suite. The proposed parser fix creates unresolved=["PARENT_KIND_CONFLICT:p"] and keeps the first parent kind. The next current inventory has a complete Actions p with VERIFY_PASS.
Actions first in v1 carrier: the old conflict is cleared; Actions+Actions produces no new conflict; PASS_ONLY_OBSERVED / VERIFY_PASS / history_complete=True (an unjustified favorable promotion).
Check Suite first: old conflict is cleared, but Suite+Actions produces a new one; UNKNOWN_HISTORY.
This order dependence remains after the previously prepared five-site #83 patch. A narrow isolated Python 3.13 transition probe confirmed both paths. This is not a full checkout or actual Devostasis pytest execution.
Required #83 acceptance addition: preserve PARENT_KIND_CONFLICT:<id> through subsequent complete-current reconciliation. Distinguish that structural contradiction from the existing HIST-15 permission for incompatible-lineage uncertainty to be repaired by genuinely complete current evidence. Retain any historical VERIFY_FAIL. Test both orderings end-to-end through reconcile with a same-revision complete current PASS and add a positive incompatible-lineage control. A repository-native pytest candidate covering those paths was syntax-compiled but NOT_RUN; no new policy/band/window/conformance identifier is proposed. If overriding a contradictory immutable parent identity is actually intended by contract, send that precise question to the research worker.
Verification limits: exact-head source inspection PASS; isolated transition probe PASS; prepared Python syntax PASS; full repository pytest, historical replay, fixing-head CI NOT_RUN. No commit or PR. Do not close #83 based only on the prior handoff.
Follow-up to the preceding order-dependent reproduction, after re-reading PR #81 HEAD a4761daa9fa87026ea106a3d722e7299b3de3b8b, src/devostasis/revision_history.py blob e7c871965c2f783ae6991d6d2c6d20596e81daa7, and the accepted HIST-15/HIST-19 wording in docs/spec/integrity-ci.md.
Sixth source-site candidate, in reconcile(), following the five-site #83 structural-admission candidate:
if unresolved and visible and all(parent_complete(p) for p in visible):
- unresolved = []+ # Complete current attempts repair evidence gaps, not immutable-kind conflicts.+ unresolved = [reason for reason in unresolved+ if reason.startswith("PARENT_KIND_CONFLICT:")]
This retains PARENT_KIND_CONFLICT:<id> across repeated carriers even when the visible current Actions parent is complete. It still clears LINEAGE_INCOMPATIBLE:... for a genuinely repairable predecessor when current evidence is complete, and does not discard previously observed VERIFY_FAIL. The addition is a narrow implementation correction, not a new threshold or a redefinition of historical rules. It needs independent review to establish whether other unresolved-reason classes must remain sticky.
Prepared test extension: 4 repository-native pytest cases (two parent-kind orderings, absorbing historic failure, valid incompatible-lineage repair), in addition to the previously prepared 65 cases; 69 proposed cases total, not pytest-collected. Offline guarded installer now proposes all six substitutions, accepts only a clean feature/ or fix/ branch at the exact reviewed SHA, verifies exact source blob, and refuses changes to master/release branches. The package is retained as a local handoff (SHA-256 6f9b866ccbab0312c470caf5c05bbc1689229204633f86276a0a49e7450895b4), not attached to GitHub.
Verification (limited): Python syntax compilation PASS for handoff files; six expected text substitutions match a controlled exact-source excerpt, not a real checkout application; bounded simplified transition probe PASS for both orderings/failure/repair controls. NOT_RUN: actual Devostasis pytest, four-generation replay, wheel/build, fixing-head CI. The observed upstream #81 Actions runs are still action_required (NOT_PASS). No source commit, PR or merge was performed. Keep #83 and the release gate open.
Activity
andy-zen-dev commentedon Oct 22, 2026
Implementation-ready source repair for the existing release chain
Base checked:
a4761daa9fa87026ea106a3d722e7299b3de3b8b;src/devostasis/revision_history.pyblobe7c871965c2f783ae6991d6d2c6d20596e81daa7. The same blob was read at the current #57/#59/#64/#69 heads. This is a proposed patch, not a committed fix or closed issue.Suggested standalone regression module
tests/test_carried_array_admission.py(avoids reapplying the obsolete current-inventory patch stack):15 malformed cases + 6 omission/empty compatibility cases + 1 evaluator-boundary case. Full checkout execution, store-chain replay and full pytest remain required; syntax/context checks alone are not acceptance. Keep the defect open until the fix is committed, verified and independently reviewed.
andy-zen-dev commentedon Oct 23, 2026
Independent exact-head reconciliation gate for #83 (2026-10-23)
Inspected at PR #81 head
a4761daa9fa87026ea106a3d722e7299b3de3b8b:src/devostasis/revision_history.pyblobe7c871965c2f783ae6991d6d2c6d20596e81daa7,src/devostasis/vitals/integrity.pyblobda6b6e91af0dfb6d75ad1f853b8bf8465f0e105d, and existingtests/test_revision_history.py.Narrow finding: the prior candidate patch is sufficient at the parser boundary; the downstream fail-closed handling already exists.
reconcile()catchesHistoryShapeError, recordsSOURCE_MALFORMEDand aREVISION_HISTORY_CARRY_MALFORMED:...problem.integrity._evaluate_revisions()seesreconciled.problemsand returns_unknown(...), whoseband=Noneandevaluation_status=UNKNOWN. No independent alteration of the Vital bands or history semantics is justified.Strengthen the pending evaluator regression beyond asserting only that a diagnostic exists. Use a fully populated positive current sample (four recent PASS revisions) to prove a malformed predecessor cannot still produce a favorable exact band. Parameterize all three offending arrays and five explicit false-like invalid values:
This adds the specific 15 evaluator-level no-false-success obligations (not just 15 parser exceptions) while reusing the existing test helpers/imports shown in the earlier comment. Keep its six allowed omission/empty-array controls, plus valid v1/v2 historical replay. It does not reopen current-series or attempt-coverage changes.
Verification status: exact-head static control-flow inspection PASS; proposed 15 new evaluator cases NOT_RUN; full pytest, four-generation bundle replay and hosted CI NOT_PASS/NOT_RUN. Current PR #81 CI runs remain
action_required. Do not close #83 or merge #81/#75 on this analysis alone.andy-zen-dev commentedon Oct 23, 2026
Executed isolated red/green verification for #83 (2026-10-23)
Re-read the exact
_carried_recordsimplementation from PR #81 heada4761daa9fa87026ea106a3d722e7299b3de3b8b,src/devostasis/revision_history.pyblobe7c871965c2f783ae6991d6d2c6d20596e81daa7. This is a verification follow-up to the existing concrete patch in comment 6334241779, not a new semantic contract or new Issue.Executed a standalone Python 3.13.5 harness containing the exact
_carried_recordsbody as read from that head, plus narrow helper stand-ins for type/parent semantics.None,False,0,"",{}across v2parent_groups, v2unresolved, v1parents) silently accepted as empty evidence.HistoryShapeError.git apply --checkand application PASS on a representative reconstructed function excerpt, not a checkout of the full repository.Exact scope: Replace
record.get("parent_groups") or []andrecord.get("unresolved") or []withrecord.get(key, []); for v1, first type-checkprevious_parents = record.get("parents", [])as a list before mappingparent_from_current. No new Integrity rule/version, band, window or history state is proposed.Acceptance still required before release: apply through a focused feature PR into the active release branch; execute actual
pytest, historical four-generation bundle replay and hosted checks at the new exact head; obtain an independent later-run review. Current #81 hosted Actions runs still reportaction_required(NOT_PASS). This comment is executed parser-boundary evidence only; it does not claim that upstream code changed.Working copy patch SHA-256:
ebb47dba90a122faf666d324823c205362118a1a47e10c67e265b44e55095266.andy-zen-dev commentedon Oct 23, 2026
#83 handoff refinement: preserve failing evidence on both historical carrier lineages (2026-10-24)
Reviewed exact base remains PR #81
a4761daa9fa87026ea106a3d722e7299b3de3b8b,src/devostasis/revision_history.pyblobe7c871965c2f783ae6991d6d2c6d20596e81daa7; existing implementation patch is in comment 6334241779. No repository source write or new PR is claimed.I prepared an exact-blob-guarded offline patch applicator plus a 38-instance pytest regression module. This extends the previously prepared 36 cases with two explicit positive controls: a real
VERIFY_FAILattempt must continue to replay asFAILURE_OBSERVED/VERIFY_FAILfor both the v2parent_groupscarrier and the v1parentscarrier. This ensures that hardening malformed-array admission cannot discard previously established failures.The 38 instances are: 15 explicit malformed-array parser rejections, 15 public Integrity no-false-success checks with four current passing revisions, 6 omission/empty-array compatibility checks, and 2 v1/v2 failing-parent replay checks. The script checks the full source blob hash, requires a non-
masterfeature checkout, and refuses missing/changed source occurrences. Its three substitutions and reapplication refusal were verified against a representative exact source-line excerpt; Python compilation PASS. Real repository pytest, historical bundle replay, and hosted CI at a fixing HEAD are NOT_RUN.Acceptance still requires a maintainer with
pushto apply the existing three-site patch on a feature branch targetingrelease/0.6.0, add all the above tests, run the actual full suite and historical bundle checks, and obtain later independent review. The earlier GitHub-side runner remainsaction_required(NOT_PASS). Do not close #83 on handoff evidence alone.Safety correction (2026-10-24): patch applicator must refuse release branches
The handoff's offline
apply_carrier_fix.pyformerly rejected onlymasterand detached HEAD. That inadvertently permitted direct source writes onrelease/0.6.0, contrary to the repository's feature/fix PR discipline. This corrects the handoff tool, not Devostasis production code.After
git branch --show-current, check:Verified the amended applicator locally in temporary Git repositories: 3/3 refusal controls PASS (
master,release/0.6.0, unrelatedfeature/issue-83base); Python compilation PASS. The old three-source-line fix and 38 proposed regression cases remain unchanged. NOT_RUN: real Devostasis checkout/pytest, 4-generation replay, wheel CI; these must still be run after a legitimate feature PR. No repository commit/PR/merge is claimed.andy-zen-dev commentedon Oct 23, 2026
#83 additional upstream coercion path in 0.1.x replay (exact #81 head)
Base: PR #81
a4761daa9fa87026ea106a3d722e7299b3de3b8b;src/devostasis/revision_history.pyblobe7c871965c2f783ae6991d6d2c6d20596e81daa7. This is adjacent to, but not fixed by, the existing three-site_carried_recordscandidate.In
carried_observation(), the fallback for a pre-carrier (0.1.x) predecessor reads itsci.revision_verdicts_14dobservation as:Thus a predecessor whose series claims
AVAILABLEorPARTIAL, but explicitly containsvalue: null,false,0,"", or{}, is silently converted to an empty, AVAILABLE v1 carrier (lineage=REPLAYABLE_LINEAGE,records=[]). The downstream_carried_records()cannot reject the original bad shape because it has already been erased. This defeats the same fail-closed admission objective for the legacy replay entry path.Executed bounded reproduction: copied the source's
carried_observation,_in_window, and_replay_sourcebodies into an isolated Python 3.13 harness with minimal observation/time stand-ins. The existing code normalized 10/10 invalid inputs (five values × statuses AVAILABLE/PARTIAL) torecords=[]. A candidate change preserved the invalid types in 10/10 cases; valid empty-array and a v1 record containing an observedVERIFY_FAILremained intact. This is not a full checkout/integration pytest and does not prove every downstream behavior.Minimal independent structural repair suggestion (preserve malformed
AVAILABLE/PARTIALvalues for the already-presentreconcile() -> _carried_records() -> HistoryShapeError -> SOURCE_MALFORMEDpath):The separate handling of non-AVAILABLE/PARTIAL statuses is unchanged here; whether it needs a stricter historical contract is out of scope. No Vital threshold/band rule or lineage identifier is changed.
Acceptance addition to #83: exercise malformed
AVAILABLE/PARTIALlegacy predecessor series (all five values) through the actual bundle/reconciliation/Integrity evaluation, assertREVISION_HISTORY_CARRY_MALFORMEDandUNKNOWNrather than an apparently empty historical carrier; retain genuinely empty arrays and v1 failing-parent replay; run full tests/four-generation historical replay at the eventual fixing head.Write boundary: no source commit/PR/merge or full-repo test is claimed; upstream PR #81 remains blocked and must be independently reviewed after a fixing commit.
Consolidated four-site #83 delivery handoff — 2026-10-24
Prepared a single offline, exact-source-blobs guarded repair covering both existing carrier-reader admission (the 3 changes in comment 6334241779) and the legacy pre-carrier v1 replay normalization described above. This is a prepared local handoff, NOT an upstream commit or PR. Do not treat it as release acceptance.
Fourth production-site replacement in
carried_observation(relative to exact PR #81 HEADa4761daa9fa87026ea106a3d722e7299b3de3b8b, blobe7c871965c2f783ae6991d6d2c6d20596e81daa7):New real-repository regression design (
tests/test_legacy_history_carrier_admission.py): for eachAVAILABLE/PARTIALpredecessor withvalue in [None, False, 0, "", {}], verifycarried_observationpreserves the invalid value (10 cases) andintegrity.evaluateemitsREVISION_HISTORY_CARRY_MALFORMEDwithUNKNOWNand no band even against four currently passing revisions (10 cases). Confirm actual[]remains compatible for both statuses (2 cases), and a valid legacyVERIFY_FAILparent remains failing (1 case). Combined with the previously prepared 38 cases, this is 61 proposed pytest instances.Executed local checks: all four exact-source-line substitutions applied/compiled in a representative code excerpt; reapplication was refused; a source-copied legacy stand-in preserved 10/10 malformed values instead of silently emptying them and preserved 2/2 genuine empty arrays; all prepared Python modules compile. NOT_RUN: those 61 actual repository pytest cases, full pytest, historical four-generation replay, wheel/sample verification and upstream CI (the two
a4761daaActions runs are stillaction_required, NOT_PASS).The offline applicator refuses protected/detached branches, wrong HEAD/blob, unclean trees and overwrite of existing tests; keep its files outside the checkout and apply only on a focused
fix/orfeature/branch. Before declaring #83 resolved: commit the four-site change + tests into a focused PR targetingrelease/0.6.0, run full and historical tests at the fixing HEAD, and obtain independent later-run review.andy-zen-dev commentedon Oct 24, 2026
#83: v1 replay silently discards parent-kind conflicts (2026-10-24)
Exact source: PR #81 HEAD a4761da; src/devostasis/revision_history.py blob e7c871965c2f783ae6991d6d2c6d20596e81daa7. This is an implementation admission error under the existing durable-history contract, not a new Vital policy.
In _carried_records(), the REPLAYABLE_LINEAGE (0.1.x) branch computes merge_parents(parents)[0], discarding the second return value (PARENT_KIND_CONFLICT:). union_record(..., []) then treats the contradiction as if it never existed.
Minimal malformed v1 carrier: one revision has two parent objects, both with parent_id = "p", current_attempt = 1, and attempts_observed = [{"attempt":1,"state":"VERIFY_PASS"}]. The first object has kind = "github_actions_workflow_run"; the second kind = "github_actions_check_suite". With the same evidence but different input order:
Minimal source repair, alongside the existing four-site #83 candidate:
The downstream reconcile() already propagates conflicts as unresolved; LINEAGE v2 already refuses duplicated parent IDs across groups. This change aligns v1 replay with existing rules rather than tuning semantics.
Executed verification: isolated Python 3.13.5 source-faithful helper reproduction with 7/7 assertions PASS, including both input orders, distinct/same-kind controls, a retained conflict and an absorbing failure. This is NOT a real package pytest. Prepared a fifth exact-context replacement and four additional pytest scenarios, bringing the prior 61 prepared cases to 65 proposed cases. Local preflight of all 5 substitutions and patched-fragment compilation PASS; installer and test modules parse. Full checkout, 65 actual pytest instances, historical bundle replay, hosted CI and fixing PR are NOT_RUN/NOT_DONE. This issue comment does not land code; account andy-zen-dev has pull=true, push=false.
Acceptance addition: a conflicting v1 parent kind must never become favorable solely because the Actions-kind entry appears first. Preserve failure absorption and valid same-kind behavior; use a focused feature PR targeting release/0.6.0 and a later independent exact-head review. Contract question #87 is separate.
andy-zen-dev commentedon Oct 24, 2026
2026-10-24 — #83 downstream regression: the v1 parent-kind conflict can still disappear
Exact re-read: PR #81
a4761daa9fa87026ea106a3d722e7299b3de3b8b(open, baserelease/0.6.0),src/devostasis/revision_history.pyblobe7c871965c2f783ae6991d6d2c6d20596e81daa7. This corrects my earlier #83 comment #6379109245: keepingmerge_parents(...)[1]asunresolvedduring the v1 parser step is necessary but not sufficient.Proof by source transition: a 0.1.x carrier has two parents with the same
parent_id="p", each with attempt 1 =VERIFY_PASS; one isgithub_actions_workflow_run, the othergithub_actions_check_suite. The proposed parser fix createsunresolved=["PARENT_KIND_CONFLICT:p"]and keeps the first parent kind. The next current inventory has a complete ActionspwithVERIFY_PASS.The current
reconcile()then runs:PASS_ONLY_OBSERVED / VERIFY_PASS / history_complete=True(an unjustified favorable promotion).UNKNOWN_HISTORY.This order dependence remains after the previously prepared five-site #83 patch. A narrow isolated Python 3.13 transition probe confirmed both paths. This is not a full checkout or actual Devostasis pytest execution.
Required #83 acceptance addition: preserve
PARENT_KIND_CONFLICT:<id>through subsequent complete-current reconciliation. Distinguish that structural contradiction from the existing HIST-15 permission for incompatible-lineage uncertainty to be repaired by genuinely complete current evidence. Retain any historicalVERIFY_FAIL. Test both orderings end-to-end throughreconcilewith a same-revision complete current PASS and add a positive incompatible-lineage control. A repository-native pytest candidate covering those paths was syntax-compiled but NOT_RUN; no new policy/band/window/conformance identifier is proposed. If overriding a contradictory immutable parent identity is actually intended by contract, send that precise question to the research worker.Verification limits: exact-head source inspection PASS; isolated transition probe PASS; prepared Python syntax PASS; full repository pytest, historical replay, fixing-head CI NOT_RUN. No commit or PR. Do not close #83 based only on the prior handoff.
Prepared sixth-site reconciliation fix — 2026-10-24
Follow-up to the preceding order-dependent reproduction, after re-reading PR #81 HEAD
a4761daa9fa87026ea106a3d722e7299b3de3b8b,src/devostasis/revision_history.pyblobe7c871965c2f783ae6991d6d2c6d20596e81daa7, and the accepted HIST-15/HIST-19 wording indocs/spec/integrity-ci.md.Sixth source-site candidate, in
reconcile(), following the five-site #83 structural-admission candidate:This retains
PARENT_KIND_CONFLICT:<id>across repeated carriers even when the visible current Actions parent is complete. It still clearsLINEAGE_INCOMPATIBLE:...for a genuinely repairable predecessor when current evidence is complete, and does not discard previously observedVERIFY_FAIL. The addition is a narrow implementation correction, not a new threshold or a redefinition of historical rules. It needs independent review to establish whether other unresolved-reason classes must remain sticky.Prepared test extension: 4 repository-native pytest cases (two parent-kind orderings, absorbing historic failure, valid incompatible-lineage repair), in addition to the previously prepared 65 cases; 69 proposed cases total, not pytest-collected. Offline guarded installer now proposes all six substitutions, accepts only a clean
feature/orfix/branch at the exact reviewed SHA, verifies exact source blob, and refuses changes to master/release branches. The package is retained as a local handoff (SHA-2566f9b866ccbab0312c470caf5c05bbc1689229204633f86276a0a49e7450895b4), not attached to GitHub.Verification (limited): Python syntax compilation PASS for handoff files; six expected text substitutions match a controlled exact-source excerpt, not a real checkout application; bounded simplified transition probe PASS for both orderings/failure/repair controls. NOT_RUN: actual Devostasis pytest, four-generation replay, wheel/build, fixing-head CI. The observed upstream #81 Actions runs are still
action_required(NOT_PASS). No source commit, PR or merge was performed. Keep #83 and the release gate open.