Releases: drevendev/Devostasis
Release list
Devostasis 0.1.9
Four things in one release. First, the adoption of the research judgements
that had been delivered and not adopted, which the roadmap's standing
obligation puts before queued work: one Integrity and one Clutter rule
version, one accepted diagnostic under an existing rule, eight accepted exact
vectors and thirty-one cases of three judgements, plus the vector kinds those
cases needed. Second, the review pass of 2026-09-22 (issue #30). Third, the
repairs of the research audits of 2026-09-20 to 2026-09-24, which were
handed off on Drive and had no record in this repository until the review
of 2026-09-25 catalogued them in issue #35. Fourth, the review of
2026-09-30 (issue #48), which found defects in this release's own new code
(among them an Integrity superset that could omit the band it emitted,
replaced by the accepted totality rule) and older ones in verification,
collection, the store and the command line, and filed what needs a decision
as #38 to #47. No threshold, window or gauge changed; the two band rules
that changed did so under accepted judgements, and their rule_id moved
with them.
- Integrity rule
integrity.bands.v1+ci-unit-004. Four accepted
judgements, one rule version, oneRULE_VERSION_BOUNDARYper project.
PV-REV-INTEGRITY-UNKNOWN-001(issue #13): a newest in-scope revision whose
current verdict isUNKNOWNnever inherits an older decisive verdict; the
Vital isUNKNOWNwith no band, the decisive history stays inderived,
andCURRENT_VERDICT_UNKNOWN:<revision>names the cause. Positively
observedNOT_EXECUTEDandNON_VERIFY_TERMINALkeep the accepted
fallback. Before this, four passes and a neweststartup_failureproduced
CLEAN / AVAILABLE / EXACT, and since 0.1.8 a falseIMPROVED.
PV-REV-TEST-003(issue #12 finding 3): a required revision series that is
PARTIALisUNKNOWNwith no band, its counts visible and marked; the
DEGRADEDpath with a fixed three-band tail called a superset is gone.
PV-REV-TEST-VECTORS-002(issue #21): one to three decisive revisions carry
sample_strength = SPARSEandCI_SPARSE_SAMPLE, four or more
ESTABLISHED.PV-INTEGRITY-TOTALITY-001(accepted by
PV-REV-INT-TOTALITY-001, #33): a newest revision still being verified is
spoken for by no older verdict; the history names a band only when it
already satisfies FAILING on its own (four or more decisive revisions, a
quarter or more failed),DEGRADED / FAILING / EXACT, and every other
history isUNKNOWNwith no band, diagnosedCI_CURRENT_VERIFY_UNRESOLVED.
This rule version first carried apossible_bandsderived from the
completions instead; the review of 2026-09-30 found it could omit the band
it emitted (777 of 7,029 shapes, the commonest being one workflow passed
and one still running) and could miss bands a completion reaches, and the
accepted contract defines no reachability algorithm at all. A positively
unconfigured repository with only non-decisive recent records is
UNINSTRUMENTEDwithCI_UNINSTRUMENTED_WITH_RECENT_NONDECISIVE_HISTORY;
an unusable series isUNKNOWNeven beside "not configured"; a verdict
outside the vocabulary isUNKNOWN, never a fallback to an older pass; a
record whose contribution contradicts its history is a defect. Cases
INT-UNKNOWN-01..06,INT-TOTAL-01..06and08..13,T2,R1,R2are
executable vectors. - Pulse diagnoses issue-only activity (
PULSE_ISSUE_ONLY_ACTIVITY,
permanent case T5, issue #22), underpulse.bands.v1as the accepted vector
requires: provenance, not a judgement about productivity. It is emitted
only when every channel was positively observed: with a channel unobserved
or a required enumeration capped, "every observed event came from issues"
would be a claim about evidence nobody has. - Clutter rule
clutter.bands.v1: incomplete evidence is a confirmed burden
floor, never a manufactured band. AdoptsPV-CLUTTER-INCOMPLETE-001
(accepted byPV-REV-CLUTTER-INCOMPLETE-001, casesCLU-INCOMPLETE-01..20,
all executable) and the readingPV-ISSUE-026-RECONCILE-001gave issue
#26. An explicitlyUNAVAILABLEissue or branch component, or aPARTIAL
count with an observed subset, no longer yields a band from the rest: the
band is the floor the observed facts prove. Observed stale work and
classified stale branches prove it; the ratio proves it only over a
complete issue and change-request domain; anUNCLASSIFIEDbranch count
proves nothing. APARTIALcount counts as an observed subset only when
its coverage says so (complete = false,
value_semantics = OBSERVED_SUBSET_COUNT, which the derivation now records
on every count aggregate of an incomplete inventory and on nothing else);
without that proof, with other semantics or with malformed coverage the
component is unresolved and diagnosedCLUTTER_PARTIAL_NOT_TRUSTED
(reviewPV-REV-PR-031-003, casesCLU-PARTIAL-TRUST-01..08; before, any
freshPARTIALvalue was promoted to a floor on its status alone, so a
saved observation set could proveHEAVYwith an estimate).
HEAVYisDEGRADED / EXACT(terminal),CLUTTEREDand
LIGHTareDEGRADEDlower bounds with a conservative superset, and a
floor of nothing isUNKNOWNwith no band. Before, an unavailable
component with nothing else observed producedDEGRADED CLEAN, a band
made from absence; on the fleet's store that is exactly one project, whose
issues are disabled and which has no stale residue: it becomesUNKNOWN,
which is what the evidence supports. The #26 case, a capped branch head
resolution, proves a floor only with explicitCLASSIFIEDretention
semantics (>= 20HEAVY exact,6..19CLUTTERED,1..5LIGHT, zero
UNKNOWN); the GitHub adapter does not emit retention semantics, so on
GitHub that case staysUNKNOWNuntil issue #22 decides whether it should.
Permanent case T7 (issue #22), theUNCLASSIFIEDupper bound with
CLUTTER_BRANCH_PURPOSE_UNCLASSIFIED, moves under the same rule id
unchanged, and when the work items alone reach the band the full count
reaches, that band isDEGRADED / EXACTas the contract's section 5 says.
OneRULE_VERSION_BOUNDARYon Clutter per project; no threshold or window
moved. The GitHub adapter still does not emitretention_semantics:
emittingUNCLASSIFIEDwould make ClutterDEGRADEDfor every project with
a stale branch and take the accepted ordering away from it, so that is a
fleet-wide decision left with issue #22, not a default. - The accepted exact vectors are in the corpus as the research process
wrote them:T2,R1,R2(PV-REV-TEST-VECTORS-002),R4
(PV-REV-TEST-VECTORS-004),R3(PV-REV-TEST-VECTORS-005),T4,T5,T7
(PV-REV-TEST-VECTORS-007). Seven of the seventy named cases without a test
now have one; sixty-three remain. - Two vector kinds and one shape, in answer to the format findings. The
cikind (issue #20) starts at the provider-native normalization: workflow
runs, their earlier attempts and check suites as the provider reports them,
through the outcome map to canonical revision records and, when the case
asks, into Integrity.R5..R10can now be materialized at the boundary they
are about;INT-UNKNOWN-02and03already are. Theactivitykind
carriesACT-COV-01..05ofPV-REV-ACTIVITY-COVERAGE-001(issue #9), the
runtime of which 0.1.7 already had.variantslets one case hold several
evidence shapes to one expectation, forvitalandcicases, which is
the one-identifier multi-variant mechanism T8 and R9 need (issue #23);
vitalcases may also assertshared_signal_groupsand
dependency_group_ids(part of T6). Every kind fails closed as before; a
provider without a normalization is an error, never a skip. - An observation not later than the previous bundle is
INCOMPARABLE
(issue #17,NON_MONOTONIC_OBSERVATION:<previous>-><current>). It was
COMPARABLE, its delta reportedIMPROVEDandWORSENEDwith the
direction inverted while citing the accepted order, andactivity.json
carried an interval that ended before it started. The bundle is still
written and immutable; it claims no direction and no interval, and
build_activityrefuses a backwards interval outright. Where such a bundle
lands is the monotonic-write policy of issue #12 finding 6, still to be
decided. - The comparison reads the immutable bundle the index names, not
latest/(issue #28). A compacted or damaged convenience copy no longer
turns the next run into aHISTORY_GAP; a copy that names a different
bundle than the index is still refused, so finding 6 stays visible. Without
an index the newest immutable bundle is found by scanning. The fleet
surfaces link to the immutable report when the copy is gone. RPT-3 now
corrupts the immutable copy, which is what its sentence always meant. - Verification binds the manifest's metadata to what the identity hashes
(issue #12 finding 4).semantic_config, the field the comparison reads,
must be the projection of the validated stored config
(SEMANTIC_CONFIG_MISMATCH); every identity field the manifest repeats must
be present in both copies and agree with the preimage
(IDENTITY_FIELD_MISMATCH), with the fields a bundle must carry and the
renderers it may name decided by its exact lineage
(UNSUPPORTED_ARTIFACT_LINEAGE,RENDERER_VERSION_NOT_IN_LINEAGE;
PV-AUDIT-MANIFEST-PREIMAGE-BINDING-001, whose concrete case was a bundle
that lost its manifestrenderer_version, kept its id, skipped the report
replay and verified with any report at all); the manifest receipt
must hash tosource_receipts_digestand be the receipt inside
observations.json(RECEIPT_DIGEST_MISMATCH,RECEIPT_COPY_MISMATCH);
andsnapshot.jsonmust name the evidence the bundle carries
(OBSERVATIONS_DIGEST_MISMATCH). A manifest o...
Devostasis 0.1.8
Roadmap targets B5 and B1: the first accepted band ordering, and the format
and runner that make a conformance case executable. No threshold, window or
gauge changed, and no rule was retuned.
- Band ordering (target B5,
PV-BAND-ORDER-001). Three Vitals now declare
which of two of their own bands is better: Clutter
CLEAN > LIGHT > CLUTTERED > HEAVY, FlowMOVING > CONGESTED > GRIDLOCKED
for a live queue, IntegrityCLEAN > FLAKY > FAILINGand
SPARSE > SPARSE_MIXED.delta.jsontherefore emitsIMPROVEDand
WORSENEDwhere the order applies. Pulse, Horizon, Direction and Debt
declare no order at all, and neither doesNO_QUEUEagainst a live queue or
an Integrity evidence state against a verdict: those transitions stay
CHANGED. No order is declared across Vitals or across projects, and none of
this is a step towards an aggregate. - A direction is only ever reported about exact measurements. The pair must
beCOMPARABLE, therule_idunchanged and both sidesAVAILABLEwith
EXACTband semantics; aDEGRADEDband is a bound, and a move between
bounds is not an improvement. The rule version boundary and observability
transitions keep precedence, and a gauge that moved inside a band is still
UNCHANGED. Every row that could have been ordered but was not says why:
BAND_ORDER_NOT_DECLARED,BAND_ORDER_INCOMPARABLEor
BAND_ORDER_NOT_ELIGIBLE. devostasis.delta.v2carries the two new classes and names the ordering
it applied inband_order_contractandband_order_version, so a stored
delta says under which order its classes were decided. This is the fourth
and, with the consumer surface now frozen, the last planned move of bundle
identity: every row of the consumer surface in the ROADMAP is stable.- Executable conformance vectors (target B1). A conformance case can now be
written as JSON and executed:devostasis.vectors.v1with avitalkind
that evaluates one Vital over raw observation envelopes and adeltakind
that compares two snapshots, a runner, adevostasis vectorscommand and a
published schema (docs/spec/vectors.md). It fails
closed: an unknown kind, an unknown key, an unknown comparison status, a
malformed envelope or a duplicate case id is an error, never a skipped case
that looks like a pass. The schema declares the partial evidence envelope a
vector actually states, and a test holds it to the envelopes the corpus
writes, so the runner and the published schema cannot accept different files. - The ordering ships as fifteen vectors, not as prose.
ORDER-01..15live
intests/vectors/band-order.json, run inside the ordinary test suite and in
CI through the command line, and the conformance table cites them as
vector:ORDER-nn. A third drift guard now checks both directions: a citation
without a vector fails, and a vector nobody cites fails. - Those fifteen carry the meanings the contract gives them. The first
version of this release derived the cases from the contract's rules instead
of transcribing itsRequired conformance casessection, which moved every
identifier fromORDER-02onward onto a different claim — a research
identifier is never reused, andconformance.mdsays so on the same page.
PV-SPEC-001found it; the cases are now transcribed, and the two accepted
pairs the corpus never executed (NO_QUEUEagainstGRIDLOCKED,
SPARSE_MIXEDtoFAILING) are executed. Semantics did not change: the
ordering itself was conformant, and no band, threshold or rule moved.
The split, adjacency and precedence cases this implementation wanted beyond
the accepted set are kept under localDEV-ORDERids, which belong to no
research unit. A fourth guard holds eachORDER-nnto the accepted case name
and to the band pairs that case names, because the first two guards pass
happily while every identifier means something else. - A vector case can state more than one pair.
given.comparisonsis a
list, each entry with its ownexpect, and the case passes only when all of
them do. Accepted cases are written that way — "GRIDLOCKED → CONGESTED → MOVINGfollows the WORSENED/IMPROVED direction" is six comparisons, "every
unequal Pulse band pair" is twelve — and splitting one across several vectors
would split its identifier.ORDER-01..15now execute 85 comparisons between
them.devostasis.vectors.v1is unchanged for the single-pair shape it
already had. - The vectors of
PV-TEST-001are still owed by the research process. The 70
named cases without a test remain open (debt D-1), but what was missing on
our side is now built, so those vectors arrive executable instead of needing
translation. - A documented pin that names a tag nobody published is now a red build.
tests/test_release_pins.pyproves the pins agree withpyproject.toml; it
cannot prove the tag they name exists, because on a release branch that tag
legitimately does not exist yet. Nothing closed the window afterwards, and
0.1.8 fell into it: every pin saidv0.1.8while master carried no such tag,
so the install command in the README failed for anyone who ran it. A new
Released pins resolveworkflow runs daily on master and resolves every
documented pin against the remote. Daily rather than per push, because the
window is legitimate for as long as it takes to tag a merge and not a day
longer. The self-observation workflow could never have caught this: it passes
devostasis-ref: ${{ github.sha }}, which is right for its purpose and means
the one live exercise ofobserve-self.ymloverrides the input that goes
stale (issue #18). - Bookkeeping: the 0.1.7 section still said "unreleased" after v0.1.7 was
tagged and released, which is the exact drift debt D-4 names.
Alongside the two targets, the defects the external review of 0.1.7 found
(#12, finding 5). Each was
reproduced before it was fixed. No contract, threshold or rule changed.
- A malformed title no longer ends a fleet run.
_titlecrashed with
IndexErroron a title that is only whitespace and withAttributeErroron
one of the wrong type. Neither is aRegisterError, so neither reached the
collector's error boundary._titleis now total for provider payload — a
commit message, change-request or issue title of the wrong type is a missing
title — while a register title of the wrong type is aRegisterErrorand
reaches the snapshot asERROR/INVALID_REGISTER, which is what the
register contract says it should be. - Linkage evidence is the exception, and it is now declared. A title or
body of the wrong type is a missing title everywhere except where the target
marker lives:_target_refsjoined the raw fields, so a non-string there
raisedTypeErrorunderplanning.source = file, and reading it as an
absent link would report a project unlinked on evidence nobody could parse.
Unreadable title, body or milestone is nowLinkageEvidenceError, a
CollectionError, so the project fails explicitly with its reason while the
rest of the fleet is still observed. A change request with no marker is
still simply unlinked, because absent evidence is a fact and unreadable
evidence is not. - A successful response that is not JSON is a declared provider failure.
UrllibTransport.getraisedjson.JSONDecodeErrorout of every handler on
an HTTP 200 with an unreadable body. It is nowApiFailurewith
MALFORMED_RESPONSE, so it becomes an observation status like every other
provider failure. - One project's failure costs one project.
run_allhad no boundary of its
own, so anythingrun_projectdid not anticipate stopped every project
queued behind it, skipped the entity-tag cache write and left the fleet index
stale. Each project now fails on its own, keeping its reason and its
unsuccessful outcome, so the run still exits non-zero.
Devostasis 0.1.7
A review of what already exists. No new capability, six defects fixed, one open question filed, two guards added. No rule, threshold, window or gauge changed.
Incomplete evidence looking complete, twice. The release collector always reported AVAILABLE with a recent_only coverage flag, so a repository with more than thirty releases had the newest thirty recorded as the whole truth; a full page is now PARTIAL with the cap reason, like every other enumeration. Downstream, a PARTIAL release inventory left no coverage note in activity.json, so even a flagged truncation read as complete in the report. No Vital reads releases, so no band was ever wrong.
Activity could declare an interval wider than its evidence. The report declares the interval since the previous bundle, as the reporting contract requires, but the inventories behind it reach back 28 days. After a longer outage the report claimed the whole gap and the unobserved part read as "nothing happened". It now carries INTERVAL_EXCEEDS_EVIDENCE_WINDOW:evidence_from=<timestamp>. Whether collection should widen to the interval instead is a question for the reporting contract, filed as issue #9.
Three smaller defects. A 304 answered to a request that carried no entity tag was treated as a successful empty body, and is now an explicit failure. A cached entry whose body was null kept its tag, so every later 304 read as a miss and refetched forever. all_projects collected a rename list that nothing consumed.
Two guards against drift. The conformance table may not cite a test that has disappeared, the specification index must link every page, and every contract identifier the runtime writes into a bundle must be findable in the specification. The last check immediately found five member schema identifiers documented nowhere, now listed in the bundle specification. That is the mechanical half of the drift debt; the semantic half stays manual.
Verified against 231 tests and all 218 bundles of the observed fleet.
Usage: uses: drevendev/devostasis/.github/workflows/observe-self.yml@v0.1.7 (see docs/deployment.md).
Generated with Claude Code.
Devostasis 0.1.6
Spend provider quota only on what changed. No rule, threshold, window or gauge changed.
A fleet run asked the same questions every day and paid full rate-limit price for answers that had not moved, and a rate-limited day degraded bands to UNKNOWN rather than reusing the previous answer. Three limits now shape how evidence is fetched, and none of them changes what it means.
- Conditional requests.
--cache <dir>keeps the entity tags of previous runs (devostasis.http-cache.v1). An unchanged answer comes back as304 Not Modified, replays the stored body, and costs a round trip but no rate-limit quota. A missing or corrupt cache costs requests, never correctness. - Bounded retries. A retryable failure waits only as long as the provider asked, through
Retry-Afteror the rate-limit reset, and only while a single wait and a total waiting budget allow it. A primary rate limit resets on the hour, so waiting it out inside a run would be a hang: that case becomes an explicitERROR / RATE_LIMITEDobservation and the run moves on. - A request budget per project,
--request-budget <n>, so one very active repository cannot starve the rest of a fleet. When it bites, a partially enumerated inventory isPARTIALand one that never started isUNKNOWN, both with the reasonREQUEST_BUDGET_EXHAUSTED, and the receipt carries a matching capability note. A short list is never reported as complete.
Receipt devostasis.receipt.v2 no longer records the request count. The receipt is identity-bearing, so without this change turning the cache on would have silently moved every bundle_id for unchanged evidence. How the evidence was fetched belongs to the client rather than to the evidence; the counts moved to the bundle's post-identity run_meta, which now also carries billed_requests, conditional_hits and retries. Bundles written under devostasis.receipt.v1 remain verifiable, because verification uses each bundle's stored preimage.
Bundle identities therefore change once for identical evidence. Comparability is unaffected: the receipt is not part of the semantic configuration.
Twenty tests cover the three limits, including one that builds the same repository with a cold and a warm cache and asserts the bundle identities match.
Usage: uses: drevendev/devostasis/.github/workflows/observe-self.yml@v0.1.6 (see docs/deployment.md).
Generated with Claude Code.
Devostasis 0.1.5
A project is its immutable id, not its path (RPT-7). No rule, threshold, window or gauge changed.
Renaming or transferring a repository used to split its history in two: the old directory became an orphan nobody read again, and the new one started at BASELINE as if the project had just been born. The immutable project id was already recorded in every bundle and used by nothing.
- The history store now locates a project by
project_identity.immutable_project_idand treats the locator as the human-readable place to put it. A renamed or transferred repository is relocated once to its new locator instead of starting a second history, and the move is recorded in the project index as arenamesentry. - Ambiguity fails closed. A locator already held by a different project is refused rather than merged, and the conflict is detected before any history is read, so
latest()can never compare against the wrong project. A repository whose old name is immediately reused by a new repository therefore yields two separate histories, because the ids differ. - An adapter that cannot prove an immutable id keeps the previous behaviour: the locator is the identity and a rename starts a BASELINE. Without proof that two names are the same project, losing continuity is more honest than guessing.
- Bundles are unchanged, including the
project_keyeach records: a bundle keeps the locator it was observed under, and moving the directory does not rewrite it. Every relocated bundle still verifies.
Twelve conformance tests for RPT-7 cover rename, transfer, an old name reused by a new repository, a locator held by another project, a conflict reported by latest(), a missing immutable id, an unchanged locator, the fleet surfaces after a rename, and verification of relocated bundles.
Also in this release: calibration finding 9, found by observing this repository. Direction counts active change requests linked to an open target, so closing a delivered target un-links the pull requests that delivered it while they are still inside the 28-day window. Never closing a target would keep the band higher than finishing the work. The finding is measured rather than reasoned and is recorded for the research process with three candidate readings.
Usage: uses: drevendev/devostasis/.github/workflows/observe-self.yml@v0.1.5 (see docs/deployment.md).
Generated with Claude Code.
Devostasis 0.1.4
The fleet as data, not only as Markdown. No rule, threshold, window or gauge changed.
A history store now carries projects/index.json beside projects/README.md, under the contract devostasis.fleet.v1 (schema schemas/fleet-index.schema.json). One entry per project: locator and immutable project id, observed_at, bundle_id, previous_bundle_id, comparison_status, the project's own attention order, one row per Vital with band, evaluation status, gauge and demand level, and relative paths to the report and to the immutable bundle the entry came from. It is written by every fleet run and by devostasis index.
jq -r '.projects[] | select(.vitals.integrity.level == "CRITICAL") | .locator' projects/index.jsonThree properties make it safe to consume:
- it adds no meaning, since every value comes from the latest bundle, which stays authoritative for provenance, coverage and the reasoning behind a band;
- there is no aggregate;
- there is no cross-project ordering, and
cross_project_orderis explicitly null, because no accepted contract says what it means for one project's CRITICAL to outrank another's. A consumer that wants a fleet-wide priority applies its own policy and owns that decision.
Two failure modes are handled rather than assumed. A bundle written before the demand interface existed yields null levels and an empty attention order rather than invented ones. The document carries no generation timestamp and is ordered by project key, so a run that changes nothing rewrites the same bytes and a version-controlled store stays quiet.
This is the last change to the consumer surface that the implementation owns. The remaining one is the band ordering contract, which decides whether delta.json ever emits IMPROVED and WORSENED, and it belongs to the research process.
Usage: uses: drevendev/devostasis/.github/workflows/observe-self.yml@v0.1.4 (see docs/deployment.md).
Generated with Claude Code.
Devostasis 0.1.3
Devostasis declares its own plan and debt, so its report about itself stops saying UNDECLARED and UNINSTRUMENTED and starts saying something a consumer can act on. No rule, threshold, window or gauge changed.
.devostasis/targets.jsonand.devostasis/debt.json: this repository's planning targets and registered maintenance obligations, maintained by hand and mirroring the phases in ROADMAP.md. They are also the worked example an adopter copies, replacing the fictional paths the specification used until now.- Self-observation reads them: the caller passes planning-source file, both register paths and a debt mapping_version, so the workflow and the fleet observation see the same metadata and cannot disagree.
- CONTRIBUTING documents the
Target: <id>line that links a pull request to a target, the rule that a due date is written only when it is real, and the boundary between a target and a debt item. - The deployment guide names this repository as the worked example and states that registers are read from the default branch, so a register on a working branch is REGISTER_NOT_FOUND until it merges.
- Every documented pin names v0.1.3, including the reusable workflow's default install ref, and tests/test_release_pins.py fails the build when a pin, the package version or the changelog section falls behind.
- tests/test_own_registers.py turns a typo in either register into a red build instead of three Vitals quietly going UNKNOWN.
Measured against the real register content rather than assumed: Horizon becomes DECLARED with ten open targets, Debt becomes PRESENT with five open items and none stale, and Direction follows the markers on active pull requests. Horizon stops at DECLARED rather than VISIBLE because no target carries a due date, and none does because none of the dates would be real.
This is the first real-repository evidence for planning.source = file and debt.source = file; until now both contracts existed only in synthetic fixtures. A project's history is INCOMPARABLE once when its configuration adopts the registers, because the semantic configuration changed.
Usage: uses: drevendev/devostasis/.github/workflows/observe-self.yml@v0.1.3 (see docs/deployment.md).
Generated with Claude Code.
Devostasis 0.1.2
The first research judgements, adopted against real bundles. No numeric threshold or window changed.
- Flow rule flow.bands.v1: a positively observed empty queue is NO_QUEUE whatever the historical merge median, and the classifier consumes the exact rational median merge latency in seconds (604800 s and 1209600 s are the exact conversions of 168 h and 336 h). The whole-hour value stays as a derived presentation projection.
- Pulse rule pulse.bands.v1: a capped required enumeration is evaluated over every admissible completion of the missing tail, giving one forced band, every reachable band in possible_bands, or UNKNOWN.
- Delta: a Vital whose rule version changed since the previous bundle is INCOMPARABLE on its own (RULE_VERSION_BOUNDARY) while the bundle stays COMPARABLE; historical bands are never reinterpreted.
- Demand devostasis.demand.v2: the attention order is level rank, then canonical Vital order. The cross-Vital gauge tie-break of v1 is removed, because gauges of different Vitals measure different phenomena; attention_key is gone.
- Verification adopts the stored effective config as the semantic authority of a bundle: fail-closed schema validation, the canonical member profile derived from it and checked against manifest, members and identity markers, and report replay only after those pass. Bundles of both effective-config schemas still verify.
- Renderer devostasis.render.v4; the GitHub CI outcome map is confirmed (timed_out is a verification failure, startup_failure is UNKNOWN).
- Documentation: gauges accepted for presentation and same-Vital ordering only; reporting decisions on permission-domain stores, optional report.html, retention, and self-observation output being convenience rather than durable history.
Bundle identities change for every project. History stays COMPARABLE; Flow and Pulse report RULE_VERSION_BOUNDARY once, on the first bundle after the upgrade.
Usage: uses: drevendev/devostasis/.github/workflows/observe-self.yml@v0.1.2 (see docs/deployment.md).
Generated with Claude Code.
Devostasis 0.1.1
Self-observation for any repository.
- Reusable workflow observe-self.yml: a repository observes itself with its own GITHUB_TOKEN (no secret), uploads the bundle as an artifact, writes the status card and attention order to the job summary, and exposes attention, attention-order, levels, bands, gauges, bundle-id and comparison-status as outputs. Optional read-only comparison against a history store.
- devostasis run --repo owner/name observes one repository from flags; devostasis actions-summary writes the job summary and step outputs.
- Devostasis observes itself weekly with the workflow it ships.
- No contract, policy or bundle change: bundles of 0.1.0 and 0.1.1 are identical for identical evidence.
Usage: uses: drevendev/devostasis/.github/workflows/observe-self.yml@v0.1.1 (see docs/deployment.md).
Generated with Claude Code.
Devostasis 0.1.0
First release: deterministic, model-free vital signs for software repositories.
Highlights
- Seven Vitals under the accepted
PV-VITALS-V1-002taxonomy: Pulse, Flow, Integrity, Clutter, Horizon, Direction, Debt. Named bands, explicitUNKNOWNandDEGRADEDbounds, declared correlations, no aggregate score. - Observation contract
RAW-OBS-V0: every fact carries a status (AVAILABLE,PARTIAL,UNAVAILABLE,FORBIDDEN,UNKNOWN,ERROR), a freshness and a receipt. Zero is only ever a positively observed value. - Integrity implements
PV-CI-UNIT-004: revision-level verdicts, provider-native parent identity, greatest-attempt current state, failure-sticky history. Retry-until-green cannot erase a failure. - Read-only GitHub adapter on the standard library, sized for very active repositories; pagination caps become
PARTIAL, tier and permission failures becomeUNAVAILABLE/FORBIDDEN. - Immutable bundles (
devostasis.bundle.v2): manifest, snapshot, delta, activity, observations, gauges, demand, persisted effective config and a deterministic Markdown report; SHA-256 identity over an acyclic preimage;devostasis verifyneeds nothing outside the bundle. - Gauges (
devostasis.gauge.v1): 0-100 position of every band on the scale of its phenomenon, persisted asgauges.json. - Demand interface (
devostasis.demand.v1): one level per Vital from an overridable band-to-level table plus an attention order,UNRESOLVEDfor missing evidence, no sum. - Register files: planning targets and debt items from
targets.jsonanddebt.jsonin the observed repository, change requests linked by aTarget: <id>marker; label-based debt mapping and GitHub milestones also supported. - Display configuration: which Vitals, which card components (bar, number, band), which report sections.
- Append-only history store with
BASELINE/COMPARABLE/HISTORY_GAP/INCOMPARABLEcomparison, activity since the previous successful bundle, and a fleet overview. - CLI:
observe,evaluate,run,build,verify,render,index,gauges,demand. - 127 conformance and unit tests named after the research cases they implement; CI on Python 3.12, 3.13 and 3.14.
Install
pip install git+https://github.com/drevendev/devostasis@v0.1.0See docs/deployment.md for the daily GitHub Actions setup with a companion history repository, and ROADMAP.md for what is deliberately deferred (GitLab, instruments, HTML report, custom templates, themes).
🤖 Generated with Claude Code