Skip to content

Release 0.6.0: offline repository analysis and executable assurance - #75

Open
abogun-product wants to merge 47 commits into
drevendev:masterfrom
abogun-product:zendreven/release-0.6.0
Open

abogun-product wants to merge 47 commits into
drevendev:masterfrom
abogun-product:zendreven/release-0.6.0

Conversation

@abogun-product

@abogun-product abogun-product commented Oct 8, 2026 •

Copy link
Copy Markdown

Cumulative 0.6.0 release candidate. Feature PR: #81. This PR uses the same final source head and retains the stacked independent review/release gates below.

Pinned source-tree replay previously trusted recorded roots, ancestry and change counts. This 0.6 increment adds bounded authenticated Git history proof and re-derives those claims offline while preserving historical bundle/packet bytes. It also materializes the remaining R11–R53 and the earlier operation cases, with actual governed evaluation, durable history and persisted bundle verification.

Target: E4
Target: B1

Final source head: a4761da.

Delivered behavior

  • Native code analysis/policy/engine/packet/comparison v2 and devostasis.git-history-proof.v1; separate exact v1 replay. Hashed raw objects establish all parent edges, roots, merge ancestry, committer-time window and declared byte-line edits. Missing/capped proof stays PARTIAL; rehashed false roots/counts/COMPLETE claims fail.
  • R11–R53: 43 permanent cases, 84 subordinate CI variants. Literal native inputs and expectations execute parent identity, explicit rerun links, exact Actions/check-suite overlap, latest-attempt selection, unresolved precedence, commit-time order/window, real-store lifecycle/expiry and broken-predecessor cases.
  • 63 permanent bridge cases across seven scenario versions, materializing the former 62-case gap plus RPT-8. Earlier RAW_RUNS, shared multi-Vital, whole T8 substitution matrix and canonical bundle/store operations remain executable. The 148 legacy CLI vectors keep their meanings.
  • Opt-in devostasis.ci-normalization.v1 produces raw native evidence, normalized records and provenance. Governed Integrity recomputes and compares all four emitted envelopes. Altered provider/project/time/version/digest/records, contradictory immutable identities, unknown fields and broken pagination fail closed. Partial acquisition cannot prove favorable complete history. The new rule has an explicit per-Vital comparison boundary; absent new inputs, historical evaluation and bundle replay remain unchanged.
  • Parent aggregates govern over children. Child-only fallback is explicitly raw/degraded, with UNKNOWN canonical parent history. GitLab pipeline identity/current state and retained failures are supported offline; favorable pipeline retry-history completeness and a core GitLab collector are not claimed. Cross-id links are acquisition evidence, not provider-signed attestations.
  • OS-locked store publication rejects stale advancing writers, preserves immutable candidates and requires rebuild/retry. Index permission denial stays FORBIDDEN/HISTORY_GAP.
  • Public schemas cover the native input and all seven bridge scenarios; Draft 2020-12 validation is a development-only dependency. Runtime remains stdlib-only.

The case-to-proof table, native CI contract and literal tests/fixtures/ci-revisions.json state the detailed R11–R53 acceptance. Exact fixture fidelity remains an independent review obligation, especially the current/history distinctions under later PV-CI-UNIT-004/PV-HIST-002 rules.

Validation

  • Full local Windows/Python 3.13 suite: 2539 passed; the subsequently added empty-carrier rejection and all six closed-lineage mutations also passed. Final CI collects 2540 tests.
  • Targeted normalization/conformance/spec checks: 111 passed; real JSON Schema validation: 10 passed.
  • 148 legacy CLI vectors and all 63 bridge cases passed offline.
  • Legacy examples/code and new examples/code-v2 regenerated byte for byte.
  • Wheel 0.6.0 built and installed in an isolated environment; core/v1/v2/work bundles, v2 packet and the installed new normalization rule verified.
  • Exact-head Python 3.12/3.13/3.14 CI: feature matrix, cumulative matrix. All six jobs and all workflow steps passed at a4761daa9fa87026ea106a3d722e7299b3de3b8b.
  • Upstream fork-workflow authorization: feature/release PR runs are action_required; maintainer approval is still required.

Independent acceptance and release boundary

PV-REV-CONFORMANCE-SURFACE-001 accepts the capability contract; PV-REV-TEST-002 accepts the permanent R-case expansion. Neither independently accepts these local fixtures or this concrete implementation. The missing-implementation-fixture debt D-1 is closed; B1 stays open for independent concrete-surface/whole-case acceptance and separate T9 cell-key delivery. B7 retains sustained outside-consumer evidence. Independent reviews are the next owner-directed phase and are not performed or claimed in this PR.

This remains 0.6.0. Supersedes readiness-only #80, includes its repairs and the cumulative 0.2–0.5 ancestry represented by #57/#59/#64/#69/#75, and targets release/0.6.0. The cumulative #75 uses the same head. Earlier release artifacts and their independent gates remain separate. External scheduling is owner-deferred (#71). No merge or release tag is performed.

Acceptance ledger for every prepared version

Checked implementation items below are execution evidence. Unchecked independent review, upstream authorization and maintainer release gates remain required.

Release acceptance through 0.6

This is the cumulative acceptance ledger for the prepared 0.2–0.6 increments.
They remain unreleased until maintainer merges/tags under CONTRIBUTING.md.
The latest published tag observed in the October 21 audit was v0.1.9.
Implementation evidence and independent acceptance are separate gates.

The assurance increment is part of 0.6.0, not a new release number. It
includes the October 21 readiness repairs and preserves older canonical bundles.
The pull request records final commit/run links; the commands below reproduce
the acceptance from a source checkout without network or private calibration.

0.2.0 — durable core history and incomplete evidence

Evidence: tests/test_ci_history_admission.py, tests/test_revision_history.py,
tests/conformance/, core example
verification. The #57 fork matrix passed on Python 3.12/3.13/3.14 at b849923.
The broader B1/B7 milestone is still open; this ledger does not silently mark
that historical target achieved.

0.3.0 — Evidence to Action

  • Five deterministic queues, explicit priority/dependencies and bounded
    acceptance; observed exact-head evidence gates merge admission.
  • SARIF/JUnit/Cobertura/performance evidence retains source/revision/age gaps.
  • Bounded handoff, cursors, conditional reads and offline replay execute.
  • Missing/forbidden/stale reports cannot satisfy acceptance.
  • Independent release review of Release 0.3.0: Evidence to Action with verified work scopes and bounded handoff #59; maintainer release merge/tag.

Evidence: tests/test_workscope.py,
tests/test_work_handoff.py, examples/work. The #59 fork matrix passed at
a41fac6 on Python 3.12/3.13/3.14.

0.4.0 — reproducible consumer handoff

  • Receipt execution mechanics are outside canonical identity; semantic
    acquisition distinctions remain identity bearing.
  • Exact historical verification precedes compatibility dispatch. Unknown,
    mixed, ambiguous or unauthorized nonidentity edges fail closed.
  • Mutable branch/change bindings resolve immutable projects and commit
    membership before/after source reads; packets bind exact verified bytes.
  • Historical work v1 and core lineages retain their own replay paths.
  • Independent review of Release 0.4.0: reproducible consumer handoff and exact contract compatibility #64 and receipt/compatibility/consumer boundaries.
  • Maintainer release merge/tag.

Evidence: tests/test_receipt_identity.py, tests/test_compatibility.py,
tests/test_work_handoff.py, historical examples. The #64 fork matrix passed
at c98e7ed on Python 3.12/3.13/3.14.

0.5.0 — Consumer Operations

  • Adopter project/policy/engine bindings reject wrong subjects before
    collection or canonical publication; disabled invocations retain negative control.
  • Shared request/deadline budgets remain bounded under parallel collection.
  • Repeated generations, immutable invocation receipts and calendar-day audit
    survive private history export, verification and restore.
  • Packet-bound outcomes remain caller reports and grant no independent acceptance.
  • Independent review of Release 0.5.0: bound consumer operations and portable private history #69 and archive/caller/budget boundaries.
  • Maintainer release merge/tag.

Evidence: tests/test_work_operations.py, examples/work/adoption.json,
CI archive round trip. The #69 fork matrix passed at aa5e0e1 on
Python 3.12/3.13/3.14. Actual scheduled outside adoption (#71), collection
qualification (#62), long-term incremental archive scale (#67) and B7 remain
explicit owner/external gates.

0.6.0 — offline analysis and executable assurance

  • Pinned SHA-1/SHA-256 source/tree/blob proofs, Python 3.12 AST/import analysis,
    conservative finding comparison, SARIF and bounded verified source packets.
  • v2 authenticates reachable raw commits, all parent edges and historical
    tree/blob objects; roots, window selection, edit counts and COMPLETE claims
    are derived again without Git, a checkout, network or source execution.
  • Merge ancestry, clock skew, shallow/missing objects, graph/object/byte/work
    caps and unsafe paths retain explicit partial states; incomplete roots cannot
    establish comparable repository identity.
  • Rehashed root/ancestor/time/count/frontier/complete forgeries, wrong object
    kinds and unused proof objects fail. An independent LCS oracle checks the
    declared byte-line edit algorithm, including repeated/unterminated lines.
  • Legacy examples/code regenerates byte for byte. New examples/code-v2
    and separate schemas replay independently; cross-lineage comparison is refused.
  • Sixty-three permanent conformance IDs execute real native normalization,
    consumed RAW_RUNS provenance, one shared multi-Vital graph, all T8 substitutions,
    canonical bundle operations and stateful HistoryStore operations.
  • R11–R53 are materialized under their 43 permanent IDs, with 84 CI variants:
    native parent identities, exact overlap, proved reruns, unresolved precedence,
    commit-time order/window and failure-sticky real-store lifecycles. Raw child
    fallback and parent-level history limits remain explicit.
  • Governed Integrity recomputes native evidence/provenance/records and rejects
    altered bindings; unknown lineage, contradictory identity, broken pagination
    and incomplete favorable history fail closed. New behavior is opt in under
    a separate rule; old bundle examples and legacy paths retain exact replay.
  • HistoryStore publication is locked; a stale advancing writer preserves
    candidates, reports conflict and rebuilds from latest. Permission failures
    remain explicit HISTORY_GAP.
  • Independent review of Git proof completeness, bounds and algorithm specification.
  • Independent review of the concrete conformance surface and exact fixtures;
    capability-level research acceptance alone does not accept this implementation.
  • Independent release/admission review of the final cumulative head, including
    the October findings on Release 0.6.0: offline repository analysis and executable assurance #75 and the included readiness fixes.
  • Upstream workflow approval where GitHub requires maintainer authorization.
  • Maintainer merges the reviewed feature into release/0.6.0, reconciles the
    cumulative Release 0.6.0: offline repository analysis and executable assurance #75 release PR, then merges/tags v0.6.0 under CONTRIBUTING.md.

Reproduce:

python -m pytest
devostasis vectors --quiet
python scripts/check_conformance_surface.py
devostasis verify --bundle examples/sample-bundle
python scripts/make_code_examples.py
python scripts/make_code_examples.py --v2
git diff --exit-code -- examples/code examples/code-v2
devostasis code verify --bundle examples/code/bundle
devostasis code verify --bundle examples/code-v2/bundle
devostasis code verify-packet --bundle examples/code-v2/bundle --packet examples/code-v2/packet.json
devostasis work verify --bundle examples/code-v2/work-bundle
devostasis work replay --bundle examples/code-v2/work-bundle
python -m pip wheel --no-deps .

CI additionally verifies both work/core examples, deterministic repeated builds
and the operations archive restore on Python 3.12/3.13/3.14. Green checks establish
those executions at the recorded head; they do not complete the unchecked gates.

The former 62-case implementation gap is materialized; B1 retains independent
concrete-surface/whole-case exact-fixture acceptance and separate T9 cell-key
delivery. B7 retains sustained
outside-consumer evidence. Legacy v1 history and omitted blob sizes keep their
documented proof limits. No compatibility migration, core GitLab collector,
threshold retuning, aggregate health score or publication is implied by this PR.

drevendev and others added 24 commits September 25, 2026 20:51
The Hungry Crab run of 2026-09-25 against pypa/build left its configuration
(.crab.yml, all defaults) and its ledger (.crab/ledger.json: one meal,
eighteen nutrients, two of them served as drevendev#36 and drevendev#37) in the working tree,
from where a roadmap commit of the 0.1.9 release branch swept them in by
accident. They were taken back out of that branch; this commit offers them
on their own, byte for byte, because the configuration says the ledger is
committed (ledger: repo) and without it the next run would propose the same
eighteen nutrients again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…versions

Direction becomes direction.bands.v2 and carries both accepted repairs in one
rule move. Linkage is state-neutral (PV-REV-DIRECTION-CLOSED-TARGET-001): a
change request linked to a declared target stays linked when the target
closes, which repairs calibration finding 9, where closing A1 and B6 took the
linked count from 2 of 6 to 0. The open-target count is still derived, for
presentation only. Every active change request is LINKED, UNLINKED or
UNRESOLVED (PV-DIRECTION-INCOMPLETE-001): a reference a complete register
lacks is a broken reference and unlinked, with DIRECTION_TARGET_REFERENCE_MISSING;
a reference nobody could resolve, or a title, body or milestone of the wrong
type, is unresolved. Over L + U + R = N the completion set k in L..L+R is
mapped through the unchanged predicates: one reachable band is DEGRADED /
band / EXACT, several are UNKNOWN. Unreadable linkage evidence therefore no
longer fails the whole project; LinkageEvidenceError is gone, and the record
names what it could not read in linkage_unresolved.

Horizon becomes horizon.bands.v2 (PV-HORIZON-PARTIAL-001). A partial target
enumeration that returned a target proves the capability; its counts are
observed-subset lower bounds, and only PH3, an open target already beyond the
frame, forces a band: DEGRADED / EXTENDED / EXACT. PH0 to PH2 stay UNKNOWN,
because Horizon declares no order to pick a representative by.

Debt becomes debt.bands.v2 (PV-DEBT-PARTIAL-001). A partial register with a
confirmed open item is DEGRADED / PRESENT / EXACT, one without is UNKNOWN,
and, as issue drevendev#39 asked for Debt, a PARTIAL count is read as a lower bound only
with its OBSERVED_SUBSET_COUNT proof.

The target marker is a standalone token now (PV-AUDIT-TARGET-MARKER-SYNTAX-001):
SubTarget: B1 and PreTarget:B1 link nothing. Counts that contradict each other
(L + U + R != N, beyond > future > open) are InadmissibleEvidence, refused
before classification and reported by the command line as an input error.

The vector format learns two things the new families need: given.derive runs
the derivation over stated inventories, so a case about how a change request
becomes linked is executed where that happens, and expect.rejected states a
refusal (HOR-PARTIAL-15). DIR-CLOSED-01..09, DIR-INCOMPLETE-01..16,
HOR-PARTIAL-01..16 and DEBT-PARTIAL-01..16 are executable vectors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Integrity history was reconstructed from whatever the provider still showed,
so a failure hidden behind a passing re-run on a parent-level surface, or
dropped by retention, left the counts as if it had never happened. The
accepted contract, PV-HIST-002 (PV-REV-HIST-002), makes history durable.

The carrier is the union of every attempt observed per parent per revision.
A build now reads its immediate predecessor, the bundle the comparison
already resolved, and adds that union as ci.revision_history_carried before
evaluating; Integrity merges it with the provider's current parents and
emits the result as derived.revision_history in the snapshot, on every path,
UNKNOWN ones included, so history also crosses a bundle whose verification
evidence could not be read. A missing, unverifiable, foreign or later
predecessor is a gap that says so (REVISION_HISTORY_GAP); nothing older is
ever carried in its place. verify checks that the source a bundle names is
the bundle its manifest follows, and a build refuses observations that
already carry history from somewhere else.

The state of a revision is a function of its union: an observed failure is
FAILURE_OBSERVED on any surface and stays; favorable evidence proves
PASS_ONLY_OBSERVED only when every attempt of every parent is observed, so a
check-suite pass, or a run whose earlier attempts are not all known, is
UNKNOWN_HISTORY (R52), which makes the Vital UNKNOWN, because T9 puts unknown
history above every conservative branch. A current verdict is never carried.
The first 0.2.0 bundle of a project replays the revision records of its
0.1.9 predecessor (lineage devostasis.ci-history.v1) instead of starting
empty. On the stored corpus every active revision is attempt-complete, so no
fleet project loses its band to R52; all 326 stored bundle directories still
verify.

The rule moves to integrity.bands.v1+ci-unit-004+hist-002; the band table
and the 0.1.9 judgements are unchanged. HIST-01..07, -09..11, -13, -15, -16
and -19 are vectors, HIST-08, -12, -17, -18 and -20 store tests; HIST-14
has no accepted migration to execute.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ligation

PV-REV-TEST-004 accepted the final T9 reconciliation (PV-TEST-004,
generator PV-T9-GEN-003) with zero CONTRACT_GAP terminals: each of the nine
gap identifiers PV-T9-GEN-002 exposed maps to one deterministic obligation,
and higher-precedence fail-closed conditions stay higher. With the Direction,
Horizon and Debt repairs of this release every obligation T9 consumes is
implemented, so T9 can be adopted.

The implementation side of it is a finite generator: the acquisition tokens
(CF, POS_ABSENT, PARTIAL, UNAVAILABLE, FORBIDDEN, UNKNOWN, ERROR, STALE)
crossed with the regions each family names, about 1,270 cells, each evaluated
and held to the accepted table: Horizon PH0..PH3, Clutter's confirmed floors,
Direction's completion set and per-reference resolution, Integrity's
unresolved, partial and unconfigured-recent regions, Debt's PD0 and PD1, and
unknown history above every conservative branch. The oracles restate the
accepted table rather than calling the evaluators. The T9v2 cell-key
serialization remains the research process's to deliver as vectors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The live run against a copy of the fleet store showed two costs the tests
could not. The first 0.2.0 bundle of trade_simulation carried its 0.1.9
predecessor's whole revision series, about a megabyte, although every record
in it had aged out of the 14-day window and would be dropped on arrival. And
its snapshot grew from 12 KB to 393 KB, because 834 workflow_dispatch runs in
two weeks attach to a handful of revisions and the carrier wrote each run as
its own object.

The carried observation now holds only in-window records, and a replayed
0.1.x record only the fields replay reads (revision, time and every parent's
identity, kind and attempts). The carrier stores parents grouped by shape
(kind, greatest attempt, observed attempts) with their ids, which is
lossless: every parent keeps its identity and its own attempts, and a
parent listed in two groups is corrupt history. On the same evidence the
snapshot is 91 KB. Which of those runs should count as verification at all
is the question issue drevendev#40 already asks the research side.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Version 0.2.0, the pins that name it, the example bundle regenerated under
the four new rule versions (its change-request records now in the shape the
adapter writes, one merged change linked to the closed release it delivered,
so the example shows the state-neutral linkage: 6 of 10 linked where the
open-target count says 5), and the changelog section.

The roadmap moves B3 to done, the Direction, Horizon, Debt and T9 judgements
to adopted, finding 9 to judged, and the count of named cases without a test
from 63 to 62. It also says plainly that 0.2.0 ships before the condition it
had set for 0.2 (Phase B closed, an outside consumer, no unadopted research):
the owner asked for a large release (drevendev#47), and this is the part of it that
rests on accepted contracts, so B7 and the Phase C contracts become the bar
for 0.3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… on it

Durable history is keyed by immutable revision identity, and the new union
code read the revision of every record directly, so a hand-written record
without one ended the evaluation with a KeyError. A record that names no
revision can be neither counted nor carried: it is now
REVISION_RECORD_INCONSISTENT, the same defect as a contribution that
contradicts its own history, and the Vital is UNKNOWN.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
B3, durable revision history, is delivered by this release. v0.2 described
the condition the roadmap had set for 0.2 (phases A and B closed, an outside
consumer, no unadopted research); 0.2.0 ships before it at the owner's
request, so the release target closes and the condition moves to a new
target, v0.3, as the roadmap now says. Ids are never reused.

The pull requests that advanced B3 stay linked after it closes: that is the
state-neutral linkage of direction.bands.v2, and this repository is its first
beneficiary.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@drevendev drevendev left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manual research handoff: two inherited Integrity admission gaps

Unit: PV-MANUAL-REPOSITORY-HANDOFF-20261014-001 (RUN-433).
Inspected exact head: 09d497f16520b6dc20f5dd42077ff76774e1f5e1.
This is an advisory COMMENT review, not approval, a blocking review event, or acceptance of a new semantic contract.

1. Extra attempt numbers can establish complete history

In src/devostasis/revision_history.py, parent_from_current() admits a parent declaring current_attempt=2 with attempts 1, 2 and 3. parent_complete() tests only set(range(1, latest + 1)) <= numbers, so union_state() returns ('PASS_ONLY_OBSERVED', True) for three passing attempts despite the contradictory declared latest attempt.

Minimal package-level reproduction for the implementer:

from devostasis.revision_history import parent_from_current, union_state
p = parent_from_current({
    'parent_id': 'github:actions:run:781',
    'kind': 'github_actions_workflow_run',
    'current_attempt': 2,
    'attempts_observed': [
        {'attempt': n, 'state': 'VERIFY_PASS'} for n in (1, 2, 3)
    ],
}, 'synthetic')
print(union_state([p], []))
# Current inspected decision: ('PASS_ONLY_OBSERVED', True)

Required repair boundary: validate attempt-number consistency before asserting completeness. Preserve legitimate successive observations of one attempt (VERIFY_UNRESOLVED then VERIFY_PASS) and failure-sticky history; do not reject every differing same-attempt state as corruption. Include missing-middle, unexpected-higher, both input orders, valid transition and retained-failure regressions. Avoid allocating a set proportional to an untrusted declared attempt number merely to check contiguity.

2. Current revision multiplicity is not protected by the carried-history repair

_carried_records() now rejects duplicate carried revisions. That is useful, but _series_records() still returns duplicate current rows and reconcile() constructs current_by_rev using last-record-wins dictionary assignment. vitals/integrity.py::_bearing() subsequently iterates the original list and can retrieve that surviving record repeatedly.

At the inspected counting/classification boundary:

  • Three unique passing revisions: 3 contributions, SPARSE.
  • Same rows with one identical duplicate: 4 contributions, CLEAN.
  • Conflicting duplicate failure then pass: 4 contributions, 0 failures.
  • Reverse order: 4 contributions, 2 failures.

This is not a claim that the normal collector emits duplicate records. It is a saved/current observation admission and reduction-consistency gap, related to #38 and the scope of #57. Please reject contradictory or duplicate current identities before reconciliation, or use an explicitly specified canonical reduction consistently in both history and counting. Duplicating a revision must never improve sample strength. Add a full ObservationSet -> evaluator -> bundle replay regression, not only a _carried_records() test.

Verification and release boundaries

Ten isolated tests of source-extracted admission/reduction/counting functions passed, including negative controls and legitimate state transitions. These are NOT full Devostasis integration tests; no repaired implementation or complete-suite result is claimed. The package-level reproduction above is supplied for that next integration check.

Both findings are present in this cumulative release head, so fixing an earlier branch alone is insufficient unless the repair reaches this head. devostasis.ci-history.v2 is already used here; do not reuse that identifier for unrelated new external-Check-Run semantics. Preserve old bundle replay and make any required compatibility decision explicit.

Publication receipt: DV-MANUAL-20261014-PR75-a438e23c.

Copy link
Copy Markdown
Owner

Manual research handoff — three independently reviewed admission gaps

Inspected head: 09d497f16520b6dc20f5dd42077ff76774e1f5e1 (2026-10-16). Advisory research communication, not approval or a gating review. This complements, rather than repeats, the October 14 review about extra attempt numbers and duplicate current revisions.

1. CI attempt vocabulary is not equivalent to known history

Prior independent judgement: PV-REV-CI-ATTEMPT-STATE-ADMISSION-001, source-level CHANGES_REQUIRED.

In revision_history.py, _attempts() accepts any string state, parent_complete() checks attempt numbers only, and union_state() treats everything except recognized FAIL/PASS as non-decisive. At this head:

  • attempt 1 = UNKNOWN → NO_DECISIVE_OBSERVED, complete True;
  • attempt 1 = UNKNOWN, attempt 2 = VERIFY_PASS → PASS_ONLY_OBSERVED, complete True;
  • attempt 1 = NOT_A_CI_STATE → NO_DECISIVE_OBSERVED, complete True.

Minimal package reproduction:

from devostasis.revision_history import parent_from_current, union_state
p = parent_from_current({
    'parent_id': 'github:actions:run:781',
    'kind': 'github_actions_workflow_run', 'current_attempt': 2,
    'attempts_observed': [
        {'attempt': 1, 'state': 'UNKNOWN'},
        {'attempt': 2, 'state': 'VERIFY_PASS'},
    ],
}, 'synthetic')
print(union_state([p], []))
# Inspected behavior: ('PASS_ONLY_OBSERVED', True)

UNKNOWN is a legitimate normalized outcome, not an invalid enum. Handle genuine uncertainty separately from unknown vocabulary. Do not turn an unknown attempt into proof that no failure occurred. Preserve failure-sticky history and legitimate successive observations of one attempt (VERIFY_UNRESOLVED → VERIFY_PASS); rejecting every differing same-attempt observation would introduce a different bug.

Verification: six freshly executed isolated tests of the inspected admission/reduction functions reproduced these three cases and three controls (valid pass, retained failure with UNKNOWN, unresolved-to-pass for the same attempt). These were not installed-package tests.

2. Current timestamps can contaminate durable CI history

Prior independent judgement: PV-REV-CI-TIMESTAMP-PARSE-001, source-level CHANGES_REQUIRED.

reconcile() checks that a current committed_at is a string but does not parse it before overwriting the durable record's timestamp. _carried_records() does parse it on the next observation and aborts the whole carrier on one malformed date. The current evaluation becomes UNKNOWN through reconciled.problems, but Reconciled.output() does not persist that problem as durable unresolved history.

The missing regression must exercise the complete chain, not only malformed-carrier rejection:

  1. B1 establishes a failure for revision R, alongside passing revisions.
  2. B2 receives R again with a malformed timestamp; its old failure must not become an invalid durable record.
  3. B3 reads the predecessor. Malformation must not silently erase established failures or repair uncertainty merely by emitting a replacement carrier.
  4. B4 supplies otherwise favorable evidence while R remains in the same complete inventory and inside the 14-day window. CLEAN must not follow solely from that loss of evidence.

This four-bundle end-to-end sequence is source-traced, not executed here. Its immediate malformed-carrier result is UNKNOWN; the concern is a later falsely favorable result. Normal GitHub collection has not been demonstrated to emit malformed timestamps.

Repair boundary: parse/admit timestamps before durable reconciliation; preserve trusted prior facts and durable uncertainty; do not skip malformed inventory rows while continuing to claim complete inventory. A repaired current carrier, true aging-out, and independently proven branch removal must remain distinguishable. Cover both current and replayable historical lineages. Do not invent acceptance of a new migration.

3. Recognized source-unavailability reasons are not evidence of their cause

Prior independent judgement: PV-REV-OFFLINE-UNAVAILABLE-REASON-001, source-level CHANGES_REQUIRED.

In codeanalysis/bundle.py, admit() validates scope predicates for ADMITTED, OUT_OF_SCOPE and UNSUPPORTED entries. Its UNAVAILABLE branch checks only the reason vocabulary.

A safe regular Python file that fits the unchanged policy can therefore be replaced by UNAVAILABLE / UNSAFE_PATH, with its source bytes removed. The path, mode and object ID remain bound to the same valid tree. Rebuilding the derived members cannot establish whether that omission was justified.

Important limit: coverage remains PARTIAL, not falsely COMPLETE. The problem is unjustified omission and suppression of findings, not a claim of cryptographic forgery or an observed incident.

Executable package-level probe for the implementer, using an ordinary temporary Git repository containing safe.py:

from copy import deepcopy
from devostasis.codeanalysis.engine import default_policy
from devostasis.codeanalysis.git import collect
from devostasis.codeanalysis.bundle import build, verify_content
config = default_policy()
raw = collect(repo, 'HEAD', config, '2026-10-16T12:00:00Z')
changed = deepcopy(raw)
entry = next(e for e in changed['entries'] if e['path'] == 'safe.py')
assert entry['status'] == 'ADMITTED'
entry.update(status='UNAVAILABLE', reason='UNSAFE_PATH')
changed['sources'].pop('safe.py')
_, members = build(changed, config)
verify_content(members)  # Must not substantiate this contradictory exclusion.

This complete probe is supplied for execution, not reported as executed.

A size-based repair needs another distinction: a Git tree authenticates mode/path/object ID, not a separately supplied size for a blob whose bytes are omitted. In a fresh Git 2.47.3 fixture, a 71-byte Python source had blob 506747696c470f5cb6cb81345532012815b5577b; declaring its metadata size as 2,000,000 did not change those object bytes or their hash. Rechecking FILE_BYTE_CAP against that same unverified number is not independent size proof.

Repair boundary: substantiate tree-backed path/mode/scope predicates and count/total-budget decisions only from trustworthy premises. Keep unavailable size claims explicitly unproven until a suitable evidence/compatibility contract exists; do not request unbounded blob reads merely to make the check pass. Preserve legitimate exclusions and deterministic budget priority. Add negative cases for all five reason classes, forged size, valid exclusions and old-format replay.

Handoff and integration

These are three independently reviewed findings being made visible at the cumulative release head. Their proposed CI-STATE, CI-TIME and CODE-UNAV regression families are not a claim of completed conformance delivery or newly accepted normative semantics. Preserve permanent accepted identifiers and make any required rule/carrier/version decision explicit. The current CI carrier already uses devostasis.ci-history.v2.

Please implement and test the finite repairs in the release chain rather than treating another unchanged watch pass as new work. Existing #35/#38 cover related admission families; #73 remains the separate ancestry/root/change-count proof issue. Neither a green unrelated matrix nor this comment establishes that these regressions passed. No code, branch, tag, workflow or repository setting was changed by this handoff.

Publication receipt: DV-MANUAL-20261016-PR75-8f12a0cd.

Copy link
Copy Markdown

Owner-requested cleanup: current CI, #63 repair, and remaining release gates

Inspected head: 09d497f16520b6dc20f5dd42077ff76774e1f5e1, 2026-10-18.

CI status correction

Upstream now has the protected release/0.6.0 branch at this exact SHA. Its push CI run 39030444073 completed successfully on 2026-10-17: Python 3.12, 3.13 and 3.14 jobs and their unit/conformance/example/replay/restore steps all succeeded. Self-observation run 39030444092 also succeeded. The older PR-triggered action_required run must not be reported as the only CI evidence for this head. These successful checks do not approve the separately reported admission gaps or cover a later repaired head.

#63 now has a concrete two-line configuration repair

The current .github/dependabot.yml blob is 03ced887bb0326c53d9754fa5a08ea762373cdbe. Both ecosystems still target release/0.3.0, which is absent upstream. The active upstream release branch now exists, so the branch-creation prerequisite described in #63 is no longer missing.

Proposed diff, preserving schedule, grouping and cooldown:

@@
-    target-branch: "release/0.3.0"
+    target-branch: "release/0.6.0"
@@
-    target-branch: "release/0.3.0"
+    target-branch: "release/0.6.0"

The patch was checked and applied against the COMPLETE original file after verifying its Git blob SHA. Both target substitutions and absence of unrelated changes passed. This is prepared code, not an upstream commit. Actual scheduled Dependabot execution is NOT_RUN; #63 explicitly requires that operational confirmation after integration, so do not close it from a text edit alone.

Integrity integration and roadmap

The revision_history.py blob at this head is still 8c246632c95e681125e7ab8ffbe44755ec0b79bb, identical to #57. A local candidate covers malformed/duplicate current inventory, immutable timestamp preservation and exact attempt-number coverage. The latter preserves legitimate successive same-attempt observations and observed failures, without allocating by an untrusted maximum.

A new regression suite imports six COMPLETE original modules, verified by Git blob identity, and exercises real ObservationSet/canonical JSON/history serialization. Baseline: 23 failed, 16 passed; repaired candidate: 39 passed on Python 3.13.5. This is module integration at #57's dependency set, NOT the complete 0.6 package/evaluator/HistoryStore/CLI/conformance suite. The source-file identity match permits preparing propagation; it does not substitute for full testing on this branch.

The October 16 UNKNOWN-attempt/vocabulary and Source Admission handoffs remain separate unresolved work. The size-proof boundary must not be silently decided by an implementation patch. The four-bundle full evaluator/store regression is still required. None of these findings is closed by the current candidate.

The owner-requested roadmap priorities are published as an applicable suggestion in review 5562151796. Preserve the existing release dependency order unless the owner deliberately changes publication policy; carry repairs into every final release head and retire #36/#37/#50 only after verifying their delivered content. Avoid reopening parallel implementations for issues already addressed by #64/#69/#75.

The connected andy-zen-dev account still has pull=true and push/triage/maintain/admin=false on upstream and the contributor fork. No branch, commit, new PR, merge, tag or settings change was made. Discussion publication is working in this cleanup; no current blanket publication blocker is being claimed.

@abogun-product abogun-product changed the title Release 0.6.0: Offline Repository Analysis Release 0.6.0: offline repository analysis and executable assurance Oct 21, 2026

@andy-zen-dev andy-zen-dev left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fresh bounded release/admission review at a4761da. This cumulative PR and feature #81 now use the same source head; the older reviews at 09d497f do not establish acceptance of this 224-file candidate.

Two concrete blockers were revalidated in the current source and are tracked separately:

  • #82: both current and historical Git-tree walkers lack per-tree duplicate-name and canonical-order rejection. Hash-valid malformed trees can give an ambiguous path inventory.
  • #83: v1/v2 carried-history arrays are still read through or [], converting explicitly malformed fields into empty evidence.

The old source-selection defect is repaired in this head (source_selection is recomputed and compared). The prior bounded-attempt repair is present as well. Do not reopen or blindly reapply those obsolete local patches. This review covers the actual admission paths/diff examined on the identical #81 head and release dependencies, not independent acceptance of all semantic changes or all conformance fixtures.

#81 has a newly published REQUEST_CHANGES for these defects. Complete the fixes in the existing feature → release/0.6.0 path, retain valid historical canonical bytes, run full tests and sample/v1/v2/work replay on the resulting exact head, then obtain independent final-head review before this master release. Keep the earlier prepared release gates, B1 fixture acceptance/T9, B7 and owner-deferred #71 explicit.

Upstream feature run 39617246533 is confirmed action_required, not a passed job matrix. Local full pytest/replay is NOT_RUN in this environment. No merge, tag, publication or issue closure is claimed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants