Skip to main content

Practice review data model

This page records the durable relationships and invariants behind practice reviews. It deliberately does not maintain exhaustive implementation inventories.

Use the executable sources for exact details:

Model at a glance

ConceptRoleRelationships
PracticeAreaWorkspace-defined grouping for practicesHas many practices; a practice may be unassigned
PracticeConfigurable criterion used by detectionBelongs to a workspace and may belong to an area
PracticeRevisionCriteria snapshot used to interpret a past resultBelongs to one practice; an observation may pin one revision
ObservationEvidence produced by one review jobBelongs to one practice and one job; may support many pieces of feedback
FeedbackOne recipient-specific piece of feedback and its delivery outcomeBelongs to one job; may draw on many observations and have many placements
FeedbackApprovalImmutable decision to approve or reject one exact feedback proposalStores the feedback ID, workspace, actor, decision context, content digest, and time
FeedbackObservationOrdered evidence binding between one piece of feedback and one observationJoins feedback to observations with a primary or supporting role
FeedbackPlacementWhere a piece of feedback was placedBelongs to one Feedback; records a summary, inline, or conversation placement
ReactionA developer response to delivered feedbackBelongs to one Feedback and retains its recurrence key

Invariants

Evidence and feedback are separate

An observation records what a review detected. Feedback records the guidance prepared from one or more observations and what happened to it. A placement records where that feedback appeared. This separation preserves observations even when no feedback is composed or delivery is withheld.

Observation rows are immutable. Practice criteria are mutable, so each observation can reference the criteria revision that applied to its review. Feedback content, provenance, and replacement link are immutable. A replacement is inserted with a link to the prior feedback before guarded lifecycle updates supersede it. Other guarded updates may change delivery state, delivery timestamp, or suppression reason.

Occurrence and recurrence have different identities

occurrenceKey prevents duplicate persistence of the same result within a job retry. recurrenceKey correlates the same evidence locus across review jobs. A new review therefore creates a new observation even when it reports a recurring issue.

The generation tool uses one outcome

report_observation asks the model for one outcome, rather than three fields whose valid combinations the model must reconstruct. Behaviour outcomes encode occurrence, assessment, and—only for a bad assessment—severity:

  • BEHAVIOR_PRESENT_GOOD
  • BEHAVIOR_PRESENT_BAD_MINOR|MAJOR|CRITICAL
  • BEHAVIOR_ABSENT_GOOD
  • BEHAVIOR_ABSENT_BAD_MINOR|MAJOR|CRITICAL
  • NO_REVIEW_OCCASION: a prerequisite situation named by the practice did not occur
  • INSUFFICIENT_EVIDENCE: the situation occurred, but the evidence read did not decide it

This is the model-facing contract. The normalizer maps it to the durable presence, assessment, and severity columns so existing projections can query each dimension. NO_REVIEW_OCCASION maps to NOT_APPLICABLE; INSUFFICIENT_EVIDENCE maps to INCONCLUSIVE. Do not expose the persistence names in practice criteria or generation prompts: they are storage vocabulary, not choices the model makes.

Each non-positive claim carries its proof shape

Every observation cites exact staged text. Outcomes that claim more than their citations also require exactly one structured evidence branch:

OutcomeRequired branchWhat it records
BEHAVIOR_ABSENT_*evidence.exhaustiveSearchsources searched, the concrete target, and the boundary not covered
NO_REVIEW_OCCASIONevidence.exclusionsources read, the practice subject, and the fact that rules it out
INSUFFICIENT_EVIDENCEevidence.missingEvidencethe open question and the existing evidence that would settle it
BEHAVIOR_PRESENT_*none beyond citationsthe cited behaviour is the proof

A missing, errored, redacted, or inadequate required source never becomes INSUFFICIENT_EVIDENCE. Readiness refuses that practice before generation, so no observation is created. INSUFFICIENT_EVIDENCE is only for available evidence that was read and remained non-dispositive.

An absent behaviour is a claim about a corpus. Every source a practice declares EXHAUSTIVE must appear in exhaustiveSearch.consulted. BEHAVIOR_ABSENT_GOOD additionally requires at least one exhaustive source, because “the harmful behaviour is nowhere here” is sound only over a bounded corpus covered whole. The claim reaches no further than the recorded boundary; it is not a clean bill of health for the repository or runtime. Both the sandbox normalizer and server admission enforce these rules.

Ordering uses observable properties

Observations have no model-reported confidence score. ObservationOrder sorts by severity where it applies, then by the number of distinct cited loci, then by stable identity. This makes ordering deterministic and derives every input from admitted evidence instead of model self-assessment.

Recipient and subject remain distinct

An observation's aboutUserId identifies the developer the evidence concerns. Feedback separately stores the subject and the recipient. They may be equal, but they are not the same concept and must not be inferred from each other.

Delivery state is an audit fact

Each feedback row retains its delivery outcome. See Evaluation Provenance Contract for state interpretation, evaluation joins, and limitations.

AWAITING_APPROVAL is actionable feedback, not suppression. A guarded decision moves it once to PREPARED or terminal DISCARDED and writes one FeedbackApproval. The digest binds the approved content, recipient, channel, and artifact target; release refuses a stale or mismatched decision. Approval records retain identifier snapshots rather than JPA relationships so account erasure does not rewrite the audit.

Read projections and access

The persistence model is not an authorization boundary. Controllers define who may see each projection:

  • developer observation list, detail, summary, and reflection endpoints are scoped to the authenticated developer;
  • the pull-request observation projection shows workspace members every relevant observation for that pull request;
  • the workspace-admin practice-review endpoints expose observations and feedback across that workspace;
  • learner-facing practice projections omit detector criteria by construction.

Keep these rules enforceable in controller authorization, repository predicates, DTO shape, and tests. Do not add a field matrix here: the OpenAPI specification is the authoritative contract for fields exposed by each endpoint.