Skip to content

PARTIAL values are lower bounds in Pulse and Debt without the subset proof Clutter now requires, and the derivation rewrites their cause #39

Open

Description

@drevendev

Found by the review of 2026-09-30, while repairing PV-REV-PR-031-003 in #31.

What happens

The research review of #31 (run 408, PV-REV-PR-031-003, CLU-PARTIAL-TRUST-01..08) found that clutter.bands.v1 read any fresh value-bearing PARTIAL count as an observed subset on its status alone. #31 now repairs that for Clutter: the derivation declares a count over an incomplete inventory an OBSERVED_SUBSET_COUNT in its coverage, and Clutter admits a PARTIAL count as a floor only with that proof.

Two more Vitals make the same inference and were outside that review's scope:

  • Pulse (pulse.bands.v1, _partial_lower_bound in src/devostasis/vitals/pulse.py): a required input that is PARTIAL, fresh and value-bearing is a lower bound for the bounded inference of PV-PULSE-REQUIRED-LOWER-BOUND-001, which the accepted contract grants only "because a newest-first enumeration was capped".
  • Debt (src/devostasis/vitals/debt.py): a PARTIAL debt.items.open_count greater than zero is DEGRADED / PRESENT / CONSERVATIVE_LOWER_BOUND.

Neither looks at what the value is. Reproduced on the head of #31, where the proof now exists but is not asked for:

pulse  [no coverage at all]: STEADY DEGRADED CONSERVATIVE_LOWER_BOUND ['REQUIRED_INPUT_PARTIAL:git.default_branch.commits.count_28d:PAGINATION_CAPPED', ...]
debt   [no coverage at all]: PRESENT DEGRADED CONSERVATIVE_LOWER_BOUND ['PARTIAL_REGISTER:debt.items.open_count']
pulse  [value_semantics=ESTIMATE]: STEADY DEGRADED CONSERVATIVE_LOWER_BOUND [...]
debt   [value_semantics=ESTIMATE]: PRESENT DEGRADED CONSERVATIVE_LOWER_BOUND ['PARTIAL_REGISTER:debt.items.open_count']

A PARTIAL value that says outright it is an estimate is still a floor.

Two related provenance defects of normalize._derived, found by the same review:

  • the reason of a PARTIAL aggregate is replaced by SOURCE_COVERAGE_INCOMPLETE whatever the source said (PAGINATION_CAPPED, REQUEST_BUDGET_EXHAUSTED, a cause that is not a cap), so Pulse diagnoses REQUIRED_INPUT_PARTIAL:…:SOURCE_COVERAGE_INCOMPLETE and cannot tell the capped enumeration its contract covers from anything else;
  • a value-less PARTIAL inventory becomes an UNAVAILABLE aggregate, which means "the source does not exist": Clutter then reads the branch component as explicitly unavailable (COMPONENT_UNAVAILABLE:branches:REQUEST_BUDGET_EXHAUSTED) instead of unresolved.

Why it is not repaired in the release

On the live path nothing changes: every count observe derives from an incomplete inventory now carries the proof, so a live PARTIAL input to Pulse or Debt is always a proven subset. The difference is only for saved or hand-written observation sets. But pulse.bands.v1 has been released since 0.1.2, and whether a hardening that changes no live output moves the rule id (one RULE_VERSION_BOUNDARY per project in the fleet) is a question for the research side. Debt also has its own accepted repair pending (PV-DEBT-PARTIAL-001, #33) on the same branch of debt.py. The review PR does fix Debt's missing freshness check (a stale partial register was a PRESENT lower bound, which vitals.md never allowed).

Proposal

🤖 Generated with Claude Code

Activity

  1. added
    for:researcherSpec disagreement or calibration finding to be read by the research process
    on Sep 30, 2026
  2. drevendev commented on Sep 30, 2026

    @drevendev
    OwnerAuthor

    #53 (0.2.0) does the Debt part as proposed: a PARTIAL debt.items.open_count is a lower bound only with value_semantics = OBSERVED_SUBSET_COUNT, under the rule version PV-DEBT-PARTIAL-001 moves anyway (debt.bands.v2), and Horizon's partial repair (horizon.bands.v2) requires the same proof from the start. Debt now also reports the source inventory's own reason (derived.partial_enumeration.source_reason_code, e.g. PAGINATION_CAPPED) without changing the derivation.

    Still open here: the Pulse part, which waits for the research answer this issue asks for, and the two normalize._derived provenance defects (a PARTIAL aggregate's reason replaced by SOURCE_COVERAGE_INCOMPLETE; a value-less PARTIAL inventory derived as UNAVAILABLE), which change live Pulse and Clutter diagnostics and belong with that answer.

    🤖 Generated with Claude Code

  3. drevendev commented on Oct 14, 2026

    @drevendev
    OwnerAuthor

    Manual implementation handoff: proof must survive the source-to-count boundary

    RUN-433 / PV-MANUAL-REPOSITORY-HANDOFF-20261014-001. Freshly inspected cumulative head 09d497f16520b6dc20f5dd42077ff76774e1f5e1 (normalize.py, vitals/pulse.py) and the existing Debt/Horizon update in this thread.

    The Debt/Horizon evaluator checks are not the whole repair. In _derived(), a value-bearing PARTIAL list gets value_semantics=OBSERVED_SUBSET_COUNT whenever the caller sets subset_count=True; the source coverage is copied but is not used to establish that its records are an authoritative monotone subset. An estimate/unproven acquisition can therefore acquire a stronger proof marker during derivation. This is the upstream concern independently recorded by PV-REV-PR-053-001, not a request to weaken Debt/Horizon's checks.

    The remaining boundaries are visible in the current source:

    • Pulse _partial_lower_bound() still checks only PARTIAL, FRESH and has_value, not subset semantics.
    • _derived() overwrites a PARTIAL source's cause with SOURCE_COVERAGE_INCOMPLETE unless explicitly overridden.
    • A value-less PARTIAL list is emitted as UNAVAILABLE, changing uncertainty into asserted absence.

    Implementation sequence: establish machine-explicit source provenance before issuing a subset marker; make Pulse consume the proof; retain the original acquisition cause and distinguish missing data from nonexistence. Negative tests should carry an ESTIMATE or absent proof through source -> derivation -> evaluator, not merely call the Vital with an already valid marker. Include valid capped subsets, malformed coverage, valueless PARTIAL, optional-channel gaps and frozen historical replay.

    Compatibility proposal (not a newly accepted rule): changing classification of previously admitted saved observations needs an explicit version boundary even if the ordinary collector output is unchanged. Coordinate Debt with its existing v2 candidate; do not silently redefine released Pulse v1.

    Two cautions prevent over-repair: independent lower bounds commits>=1 and active_days>=20 are not contradictory by themselves; active_days<=commits applies to exact paired counts from the same inventory, not arbitrarily paired floors. Also the current rolling 28-day window can touch 29 UTC dates; do not introduce a hard 28-date ceiling.

    Verification: fresh source inspection and prior accepted review cross-check; no full integration suite or newly accepted semantic contract is claimed.

    Publication receipt: DV-MANUAL-20261014-I39-d56e20bb.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    for:researcherSpec disagreement or calibration finding to be read by the research process

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions