2026-08-11 — Record contract_sha for tektree-io
rank: decision outranks: []
Section titled “rank: decision outranks: []”2026-08-11 — Record contract_sha for tektree-io
Section titled “2026-08-11 — Record contract_sha for tektree-io”Date: 2026-08-11 Status: proposed Verb: none — hand PR (see “Why not a verb” below) Slug: tektree-io MR-compliance: MR-4, MR-7, MR-12
Context
Section titled “Context”tektree-io was onboarded on 2026-08-11. petrova_onboard wrote
.petrova/contract.yaml to tektree-io/docs (merged as tektree-io/docs#4,
merge commit cdd24ca), and sweep-state recorded its git blob SHA prefix in
state/tektree-io.yaml as actual_contract_sha: 32a9088833dc.
The registry entry, added by the 2026-05-13 bulk sweep, has never carried a
contract_sha. That leaves drift detection inert rather than passing:
// cli/src/verbs/sweep_state.ts:154-156const contractDrift = actualContractSha !== null && repo.contract_sha ? actualContractSha !== repo.contract_sha : null;With no declared SHA the expression short-circuits to null. Every sweep since
onboarding has written contract_drift: null, which means “not checked” — not
“no drift”. A hand-edit or regeneration of the contract would pass unnoticed.
Decision
Section titled “Decision”Add contract_sha: 32a9088833dc to the tektree-io registry entry.
The value is the 12-char git blob SHA prefix of .petrova/contract.yaml at
tektree-io/docs@main, re-derived from origin/main immediately before this
edit (git show origin/main:.petrova/contract.yaml | git hash-object --stdin)
rather than copied from the sweep report, and confirmed equal to the
actual_contract_sha written by the sweep at fd7ef5b.
After this lands, contract_drift becomes false on the next sweep, and any
subsequent change to the contract surfaces as true.
Why not a verb
Section titled “Why not a verb”petrova_act_registry_edit is the correct substrate and its dry run was clean
(1 op, registry re-validated). It could not be applied today.
The verb co-emits its ADR at a path derived from date + slug + verb name:
docs/decisions/2026-08-11-petrova-act-registry-edit-tektree-io.md. That file
already exists on main — it is the ADR co-emitted by the earlier
integrations-applicability edit for the same slug, on the same day, merged as
#244. The path carries no disambiguator, so a second edit to the same slug
within one calendar day collides.
pr-emitter.ts:153-154 refuses to clobber it (operation: "create" against an
existing file returns FILE_ALREADY_EXISTS), so nothing would be lost. But the
emitter commits files sequentially and registry.yaml is first in the list, so
applying would push the registry commit to the branch, then fail on the ADR,
leaving a half-written branch and no PR.
Two further consequences of the same deterministic naming are worth recording:
- The verb’s branch name,
petrova/registry-edit/petrova_act_registry_edit/<slug>, is likewise collision-prone. While#244was open, a second edit for this slug would have reused its branch and rebuiltregistry.yamlfrom the local file — which at that point still held the pre-#244values — silently reverting the open PR’s own change on its own branch. This was the reason#244was merged before this edit was attempted. - Waiting until 2026-08-12 would also have cleared the collision, since the date prefix changes. That is a workaround, not a fix.
The defect belongs to the control plane, not to this consumer. Recorded here because this is where it was found; a proper fix (a disambiguating suffix on both the ADR filename and the branch name) is a petrova-codes change.
Alternatives considered
Section titled “Alternatives considered”- Apply the verb and accept the partial branch — rejected. Leaves
registry.yamlcommitted with no PR and no ADR, which is exactly the unaudited registry mutation MR-12 exists to prevent. - Defer to 2026-08-12 so the date prefix changes — rejected as the primary path. It works, but it makes the correctness of a governance edit depend on the wall clock, and it leaves drift detection inert overnight for no reason other than a filename.
- Commit directly to
main, assweep-statedoes — rejected.sweep-statewrites derived state, which any sweep can reproduce.registry.yamlis declared intent and is human-merged by rule.
Consequences
Section titled “Consequences”contract_driftfortektree-iobecomes meaningful:falsenow,trueif the contract changes without the registry following.- No other slug is touched. The edit is one line.
- The
petrova_act_registry_editcollision remains open against petrova-codes.