a757cffc78
Slice one of DEBT-DESIGN.md, with the four amendments applied. It writes nothing: no new event types, no scheduling, no clustering, no maintenance tasks. The point is to find out whether the model can represent debt this project already knows about, before committing to a durable schema. The projected type lives in domain and the fold lives in store, so the first implementation does not bake a read model into the command layer. operations owns the one action that exists, CheckDebtEligibility, which is a pure function returning explicit reasons like CheckSubmission. Signatures carry their version in the string. Normalization rules will change, and without a version that silently regroups history and moves the recurrence counts eligibility was already decided on. Observations require exactly one of event_id and legacy_ref. Imported Fxx history predates the events that would justify it, and a fabricated event id would break the provenance rule the ledger exists to enforce. Incompleteness is reported, not hidden. Manual interventions and worker observations are carried by no event type, so the ledger names both as non-durable gaps rather than reading as "no operational cost". The operational refusal reason says the intervention count is structurally zero on every current log. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CVbaKucEYBjMqVeUgJUsc1
55 lines
2.2 KiB
Go
55 lines
2.2 KiB
Go
package domain
|
|
|
|
import "testing"
|
|
|
|
// Normalization rules will change. A v2 signature must never match a v1 one,
|
|
// or changing them silently regroups history and moves the recurrence counts
|
|
// eligibility was already decided on.
|
|
func TestSignatureCarriesItsVersion(t *testing.T) {
|
|
sig := DebtSignature(DebtOperational, "lease_expired", "workpc-opencode", "internal/herdr")
|
|
if sig != "v1:operational:lease_expired:workpc-opencode:internal/herdr" {
|
|
t.Fatalf("signature %q", sig)
|
|
}
|
|
// Arity never varies, so a missing part cannot shift the fields left.
|
|
if got := DebtSignature(DebtPolish, "deferred_finding", "", ""); got != "v1:polish:deferred_finding:-:-" {
|
|
t.Fatalf("empty parts not padded: %q", got)
|
|
}
|
|
}
|
|
|
|
func TestComponentIsTwoSegments(t *testing.T) {
|
|
for path, want := range map[string]string{
|
|
"internal/store/store.go": "internal/store",
|
|
"internal/herdr/adapter.go": "internal/herdr",
|
|
"cmd/orchestra-worker/main.go": "cmd/orchestra-worker",
|
|
"BURNIN.md": "BURNIN.md",
|
|
"": "",
|
|
} {
|
|
if got := DebtComponent(path); got != want {
|
|
t.Fatalf("component(%q) = %q, want %q", path, got, want)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Imported history predates the events that would have justified it. A
|
|
// fabricated event id would break the provenance rule the ledger enforces.
|
|
func TestObservationNeedsExactlyOneProvenance(t *testing.T) {
|
|
sig := DebtSignature(DebtOperational, "x", "", "")
|
|
both := DebtObservation{EventID: "e1", LegacyRef: "BURNIN.md:F18", Kind: ObservationBlockReason, Signature: sig}
|
|
neither := DebtObservation{Kind: ObservationBlockReason, Signature: sig}
|
|
if both.Validate() == nil || neither.Validate() == nil {
|
|
t.Fatal("exactly one of event_id and legacy_ref must be required")
|
|
}
|
|
for _, ok := range []DebtObservation{
|
|
{EventID: "e1", Kind: ObservationBlockReason, Signature: sig},
|
|
{LegacyRef: "BURNIN.md:F18", Kind: ObservationBlockReason, Signature: sig},
|
|
} {
|
|
if err := ok.Validate(); err != nil {
|
|
t.Fatalf("valid observation refused: %v", err)
|
|
}
|
|
}
|
|
stale := DebtObservation{EventID: "e1", Kind: ObservationBlockReason, Signature: "v0:operational:x:-:-"}
|
|
if stale.Validate() == nil {
|
|
t.Fatal("a signature from another version must be refused")
|
|
}
|
|
}
|