Practice review glossary
This glossary is the canonical language for AI-supported practice mentoring and the versioned evidence contract. Use product terms in human-facing copy and the corresponding machine terms in contracts; do not invent synonyms. The broader practice feedback language remains canonical for observations and feedback. For how the words fit together at runtime — the four stages, and the refusal vocabulary each one owns — see the practice review pipeline.
Product terms
| Term | Plain meaning | Do not use for this concept |
|---|---|---|
| AI-supported practice mentoring | The product experience in which Hephaestus uses connected work to offer practice-focused guidance while leaving room for self, peer, and human mentor context. It is support, not grading or a replacement for a person. | autonomous mentoring, performance scoring |
| Practice review | One evidence-bounded operation within AI-supported mentoring: Hephaestus checks one or more practices against a specific piece of work and may produce observations. The practices it checks are the ones selected when the review starts. | practice detection, scan, mentoring relationship, run, assessment |
| Automated review | The technical capability that lets Hephaestus perform a practice review. Prefer AI-supported mentoring in author-facing UI. | detection, detector capability, judgment |
| AI-supported mentoring | Hephaestus may review connected work and offer guidance when every required source is ready. | AI mentor, guaranteed feedback |
| Human review needed | Connected evidence is not enough for responsible AI guidance. The practice remains useful for self, peer, or mentor review outside the current product, and Hephaestus skips it. | human context needed, unobservable, not applicable |
| Guidance only | Keep the practice's criteria and guidance without asking Hephaestus to review it. | practice guidance only, invalid practice, human-only |
| Review mode | The implementation Hephaestus uses when automated review is configured. | observability, mechanical/semantic classification |
| No automated review | Hephaestus does not review work against this practice. | human-only, unobservable |
| Automated-review policy | The frame a review runs in for one practice: the source-contract version, the review mode, the refusal behaviour, and the known limits. Sources belong to the bindings, not here. | evidence requirements |
| Practice binding | The one occasion a practice is reviewed on, and the evidence a review occasioned that way reads. A practice declares exactly one. | trigger, review event, schedule, bare "binding" |
| Model binding | Which AI model, with which execution limits, a workspace runs a given purpose on. Lives in Administration → AI models, not in the practice catalogue. | bare "binding", practice binding, agent config |
| Signal | The name of an ingested event a binding can be occasioned by, such as scm.pull_request.merged. Its prefix is the artifact kind, which is why a practice never states its artifact kind separately. | trigger event, webhook, hook |
| Evidence requirement | One source a binding reads, and the stance the practice takes towards it. | required evidence, evidence declaration, detector configuration |
| Evidence stance | How a practice relates to one source: REQUIRED, EXHAUSTIVE, or CONTEXTUAL. | required/optional lists, source role |
| Required capture quality | How well a source must be captured before a practice that reads it can be reviewed. It is a property of the source in the contract, not of the practice naming it. | completeness requirement, per-practice completeness |
| Evidence sufficiency | Whether passing every requirement gives Hephaestus enough context to review the practice. | evidence coverage, confidence |
| Source contract | A versioned catalog defining each source and the meaning of its states. | integration version |
| Artifact source | A registered logical input that can supply evidence. | file, mount, cache |
| Materialization | A file, database projection, cache entry, or tool result representing a source for one use. | source kind |
| Source kind | A stable identifier for one logical source, such as pull request details. | file type |
| Artifact kind | The family of reviewed work a practice is about, such as scm.pull_request. Derived from a binding's signals, never stated separately. | work type, artifact type |
| Known limitation | A claim the evidence cannot support even when every requirement passes. | blind spot, caveat |
| When evidence is insufficient | The required behavior when evidence requirements are not met. Contract 1.0.0 always skips automated review. | fallback, error handling |
| Skip automated review | Make no practice claim because the requirements are not met or the mode is unsupported. | not applicable, decline judgment, failure |
| Automated review validation | Who stands behind a practice's automated-review policy, bound to the exact review-rule fingerprint. Its only status is AUTHOR_DECLARED. | certification, approval |
| Source authorization | Instance governance permits a source for an explicit product use. | enabled, available |
| Source-use purpose | Why Hephaestus processes evidence, such as automated review or feedback delivery. | audience, recipient |
| Audience / recipient | Who may receive or inspect evidence. | purpose |
| Review readiness | For one review, Hephaestus supports the configured mode, the declared evidence is sufficient, and every required source passes its checks. | validation, activation |
| Practice autonomy | Who may authorize feedback for one practice: nobody (OFF), a workspace owner or administrator (HUMAN_APPROVAL), or the system (AUTOMATIC). Nullable at practice and group levels, where null means “inherit”. | review tier, loudness tier, shadow mode, enabled |
| Effective autonomy | The autonomy in force after resolving practice → group → workspace. Always server-resolved and reported with its source. | autonomy override |
| Review coverage | Which repositories' and which workspace members' work may be reviewed. Repository and person modes are independent; effective coverage is their intersection. | filter, audience, pilot allowlist, review scope |
| Delivery status | Whether new external practice feedback may leave a workspace (ACTIVE or PAUSED). Pausing does not stop review or erase coverage. | review status, practice autonomy, Silent Mode |
A practice author defines requirements. That definition is not proof that the evidence is sufficient or that a
review is accurate, and the product says so rather than implying otherwise: every shipped policy is its
author's declaration, and AUTHOR_DECLARED is the only status the API can return. Nothing validates a policy
independently, so no surface may suggest something did.
“Mentoring” describes the product goal, not an anthropomorphic claim. Hephaestus does not know a developer's intent, private conversations, runtime conditions, or learning needs unless an authorized source explicitly provides that context. An observation is a bounded record of observed work, not a grade, diagnosis, or ground truth.
Who may review
Review is relational: it has a reviewer, reviewed work, a practice, a procedure, evidence, and a time. Do not label a practice as universally observable or unobservable.
| Reviewer | Current system support |
|---|---|
| Hephaestus | Modeled by automatedReview and the governed evidence each binding declares. It can only use authorized, connected evidence. |
| Developer | A self-review may be possible for a specific practice; Hephaestus does not collect it. |
| Peer | A peer review may be possible from team context; Hephaestus does not collect it. |
| Human mentor | A mentor review may be possible from interpersonal or private context; Hephaestus does not collect it. |
Human practice assessment is outside the product. Proposal approval authorizes delivery of Hephaestus's existing feedback; it is not a second assessment. None of the three human reviewers above has consent, provenance, retention, access, a rubric or a validation model here, and a human review would need all six plus a record of who reviewed and in what relationship to the author. Human reviews may use different rubrics and evidence, and disagreement between two of them is two provenance-bearing reviews, not a contradiction to resolve into one ground truth. A statement that a person could observe something must never let Hephaestus attempt an automated review.
How a review was occasioned
Three separate words describe the start of a review, and they are not synonyms. The door is what a
person or a provider did. DiscoveredVia is how we came to know about the occurrence, recorded on every
signal. ObservationOrigin is the population any resulting observation belongs to, derived from
DiscoveredVia once and never re-decided.
| Door | Recorded as (DiscoveredVia) | UI label | Observation origin | Starts a review |
|---|---|---|---|---|
| A provider event on connected work | EVENT | Live event | LIVE | yes |
| Reconciling with the provider | SYNC | Noticed during a sync | LIVE | no, for pull requests and issues |
/hephaestus review in a merge request comment | MANUAL | Requested by hand | MANUAL | yes |
| The Review this now button | MANUAL | Requested by hand | MANUAL | yes |
| A confirmed campaign over past work | BACKFILL | Backfill of past work | BACKFILL | yes |
| A recurring sweep schedule | SWEEP | Found by a recurring check | LIVE | yes |
- The comment command and the button are indistinguishable afterwards. Both record
MANUAL; nothing downstream can tell them apart. (A third path, the dev trigger, recordsMANUALtoo.) SYNCis a dead end for connected project work — the SCM listeners return before submitting, leaving the rowRECORDED. The exception is the Slack thread sweep, which recordsSYNCand does submit. Never write "reconciliation never starts a review" without saying which artifact kind you mean.- Asking by hand is a door, never an occasion. A hand-requested review reviews every practice on that
work type whatever state the work is in, so there is nothing for a practice to opt into;
PracticeDefinitionValidatorrefuses a binding that names a manual-request signal. Do not present it as a moment an author can tick. - A recurring sweep is
LIVE, notBACKFILL.SWEEPrecords how the work was found, and the work it finds is current work that never raised an event. Its observations therefore compose and deliver exactly like an event-triggered review. Only a confirmed past-work campaign carriesBACKFILL, and onlyBACKFILLis measured-and-never-delivered. A sweep is a standing authorisation to spend and to speak.
MANUAL and BACKFILL are self-selected samples and LIVE is not, which is why they are held apart in
every behavioural read. A BACKFILL observation is additionally entitled only to IN_APP — the
developer's own practice feedback — and that entitlement is a ceiling, not an instruction: the in-app
router refuses a cluster made entirely of backfilled measurements (BACKFILL_HELD), so a backfill
observation is measured and never delivered, by construction rather than by configuration. Do not write
profile for this channel: Profile is the page at /w/{workspaceSlug}/user/{username} that the rest
of the workspace can read, and the two are different surfaces with different audiences.
Practice autonomy
PracticeAutonomy answers one question: who may authorize feedback for this practice? It is not the
whole delivery policy; recipient preferences, workspace controls, artifact validity, suppression and the
final egress guard still apply.
| Autonomy | Review runs | Feedback is composed | Release authority |
|---|---|---|---|
OFF | no | no | nobody |
HUMAN_APPROVAL | yes | yes | a workspace owner or administrator |
AUTOMATIC | yes | yes | the system, subject to delivery policy |
HUMAN_APPROVAL is an operational mode, not silent observation. An in-context unit enters
AWAITING_APPROVAL with its immutable content and target — only IN_CONTEXT feedback is approvable at
all. A workspace owner or administrator can approve that exact proposal or reject it, optionally recording
a structured reason. Approval moves the unit to PREPARED; rejection moves it to the terminal DISCARDED
state. Release then re-verifies that the approved content still matches what is about to be sent
(APPROVAL_STALE) and that every contributing practice still requires approval
(APPROVAL_NO_LONGER_ELIGIBLE), walks the delivery policy check order
again at the APPROVED stage, and reconciles a deterministic provider marker so a retry cannot post
twice. An approval overrides none of those controls.
Changing a practice to AUTOMATIC affects newly composed feedback only. Existing proposals remain explicit
workflow items; a configuration change must never release historical proposals implicitly. OFF is for a
practice that should not be measured. Moving AUTOMATIC back to HUMAN_APPROVAL is the normal quality
rollback because measurement continues while release returns to human control.
Autonomy inheritance
Autonomy is resolved server-side through one nullable override chain:
effective autonomy = practice.autonomy ?? group.autonomy ?? workspace default ?? HUMAN_APPROVAL
Null means “this level has not decided,” not OFF. Every API projection therefore carries the effective
autonomy, the raw override, its AutonomySource (PRACTICE, GROUP, or WORKSPACE), and whether it
was inherited. New unset chains fail safe at HUMAN_APPROVAL; an explicit AUTOMATIC is required before the
system may release feedback without a person.
Set or clear an override with:
PATCH /workspaces/{workspaceSlug}/practices/{practiceSlug}/autonomyPATCH /workspaces/{workspaceSlug}/practice-groups/{groupSlug}/autonomy
The body is {"autonomy":"HUMAN_APPROVAL"} or {"autonomy":null} to inherit. The catalogue filter is
?autonomy=<VALUE>, and autonomy rollups are returned by
GET /workspaces/{workspaceSlug}/practices/autonomy. Workspace review settings expose
defaultAutonomy; name DEFAULT_AUTONOMY in the PATCH reset set to clear the workspace override.
A practice whose automated-review policy cannot run is explicitly OFF and cannot inherit an autonomy
that admits review. Missing autonomy resolution fails closed for external delivery.
Review coverage and delivery status
WorkspaceReviewScope defines the workspace population that practice review may admit. It has two
independent modes:
| Axis | Broad mode | Narrow mode | Selected-empty means |
|---|---|---|---|
| Repository | ALL_MONITORED | SELECTED repositories, each optionally narrowed to exact base branches | no repositories |
| Person | ALL_ELIGIBLE | SELECTED people | no people |
Both axes must admit an artifact; within one axis, any entry matches. An empty base-branch list on a selected repository means every branch in that repository. Branch restrictions apply to pull and merge requests; issues have no base branch and are matched by repository and person only. Names are exact — there are no glob or path rules.
ALL_ELIGIBLE means every human WorkspaceMembership, and that is the only definition. Eligibility is
a membership row plus User.Type.USER; nothing consults accounts, sign-ins or identity links, so never
write that a person must have signed in — an operator will believe it and go looking for a screen that
enrols people. How a membership row comes to exist is
Who counts as a person. SELECTED is validated against
the same population, so a person who is not an eligible member cannot be selected.
The review subject for pull requests, merge requests, and issues is their author, and
PracticeReviewCoverageService.SubjectStatus records which of four things it turned out to be:
RESOLVED_LINKED_HUMAN, MISSING, NON_HUMAN, or UNLINKED. Only the first can be matched against the
person axis; the other three are never expanded to the whole eligible population. This makes coverage an
operator-selected population while preserving the recipient's delivery preference as a separate veto.
Coverage is returned as reviewScope by
GET /workspaces/{workspaceSlug}/practices/review-settings. A PATCH on the same path replaces the
complete coverage value and requires the current resource ETag in If-Match; that ETag is the settings'
configVersion, not the rollout revision, so a write that changes nothing policy-relevant still
invalidates a stale client. POST /workspaces/{workspaceSlug}/practices/review-settings/coverage-preview
returns authoritative current and proposed repository/member counts plus whether the proposal widens.
The two autonomy PATCH endpoints take no If-Match.
deliveryStatus is a separate workspace brake. PAUSED stops external practice feedback without stopping
review or deleting coverage. Resuming does not release automatic feedback admitted under an earlier
rollout revision. Undecided proposals remain explicit workflow items and are checked against current policy
if later approved. Instance Silent Mode remains the stronger instance-wide egress boundary.
Automatic admission records the current workspace revision. Any change to coverage, delivery status, the
workspace default autonomy, or post-merge delivery advances it — narrowing as well as widening; the
cooldown does not. Area and practice autonomy changes remain prospective through the proposal lifecycle
and the practice-authority check rather than a second revision counter. An artifact refused before review
records a typed terminal reason; changing coverage affects later work, not the refused occurrence.
The delivery policy check order
DeliveryPolicyResolver is the one place that turns facts into a delivery decision, and it walks a single
ordered list. The first DENIED decides; every check after it is NOT_REACHED. A question that cannot
be asked at this point in the pipeline is NOT_APPLICABLE — not a denial, and not a pass.
| # | DeliveryPolicyCheck | Denial records |
|---|---|---|
| 1 | INSTANCE_SILENT_MODE | INSTANCE_SILENCED |
| 2 | WORKSPACE_ENABLED | WORKSPACE_DISABLED |
| 3 | ROLLOUT_REVISION | STALE_ROLLOUT_REVISION |
| 4 | WORKSPACE_DELIVERY | WORKSPACE_DELIVERY_PAUSED |
| 5 | CURRENT_COVERAGE | OUTSIDE_CURRENT_COVERAGE |
| 6 | PRACTICE_AUTHORITY | PRACTICE_REQUIRES_APPROVAL |
| 7 | RECIPIENT_CONSENT | RECIPIENT_OPTED_OUT |
| 8 | ARTIFACT_ELIGIBILITY | the artifact's own reason |
The order is the argument. Instance-wide controls precede workspace ones, the rollout fence precedes every
question it could make moot, and the artifact is judged last because a closed pull request is the least
interesting thing to say about feedback that policy would have refused anyway. ARTIFACT_ELIGIBILITY
records ARTIFACT_CLOSED, ARTIFACT_MERGED or, when nothing more specific is known, ARTIFACT_GONE.
The same list runs at each DeliveryPolicyStage — COMPOSITION, AUTOMATIC, APPROVED, EGRESS — and
two checks read the stage:
PRACTICE_AUTHORITYasks whether every contributing practice sits at the autonomy this stage needs:AUTOMATICwhen the system is releasing on its own,HUMAN_APPROVALwhen a person's approval is being honoured. There is deliberately no separateHUMAN_APPROVALcheck — it could only ever reportPASSEDorNOT_APPLICABLE, and approval authority is exactly what this check already resolves.- At
COMPOSITIONthe contributing practices are not yet known, soPRACTICE_AUTHORITYisNOT_APPLICABLEon every lane. When the review has no artifact at all — a document or a conversation — coverage, recipient consent and artifact eligibility areNOT_APPLICABLEtoo, because there is no repository, no author and no unsolicited destination to judge. Workspace-enabled and rollout-revision checks still apply. External surfaces also apply Silent Mode and the delivery pause;IN_APPdoes not, because it never leaves Hephaestus.
The artifact lane is evaluated again at AUTOMATIC, at APPROVED when a person released it, and at EGRESS
immediately before the provider call — by which point every fact is known. The IN_APP and CONVERSATION
surfaces are evaluated exactly once, at COMPOSITION; from there each lane's own router applies the
origin-and-autonomy predicate and its per-lane rules, and those refusals are recorded as routing decisions
rather than as policy evaluations.
Each evaluation appends an immutable delivery_policy_evaluation row: the resolver version, the admitted
and evaluated rollout revisions, the surface (ARTIFACT, IN_APP, CONVERSATION), the stage, whether
delivery was allowed, the first decisive reason, the ordered check results, and a bounded fact snapshot —
artifact kind, repository, base branch, subject resolution, both coverage modes with their three match
flags, recipient consent, delivery status, trigger mode, and each contributing practice's effective
autonomy. The trace must not persist feedback bodies or member profile data.
Measurement and intervention
A practice review does two things, in two model turns, and the words for them are not interchangeable. Measurement records what is there; intervention decides to say something to a person and chooses the words. The test is whether the sentence can be checked against the artifact: if you can settle it by reading the work, it is measurement, and if you can only settle it by watching what the person does next, it is intervention. The seam is ADR 0029; how it runs is in the practice review pipeline.
| Term | Plain meaning | Do not use for this concept |
|---|---|---|
| Measurement | The first phase: reading one piece of work against each practice and recording what is there. | detection pass, scan, phase one |
| Observation | One measurement — one practice's answer about one piece of work, immutable for as long as it is retained. Carries an evidenceRationale and never advice. | finding, verdict, result |
| Intervention | The second phase: deciding what is worth saying now, to whom, and on which surface. | synthesis, rendering, formatting |
| Composition | The second LLM turn in the review's existing agent session. It starts only after Java has admitted the final measurements. | the composer's turn as part of the review, second pass |
| Composed feedback unit | One intervention the composition turn proposes for one channel and one practice, before any server gate has admitted it. | feedback row, draft feedback |
| Feedback | An admitted unit, written to the ledger with its channel, delivery state and the observations it rests on. | comment, message, guidance |
| Withhold | The composer's own decision that a lane is not worth writing on, recorded with a reason. | suppress, skip, drop |
| Suppress | The server's refusal to deliver feedback it was given, recorded as FeedbackSuppressionReason. | withhold, silence |
| Notes | What is composed for the mentor conversation: situation, capability, evidenceSummary, and inConversationSignal. Notes to the mentor, never a sentence for it to say — it writes the turn from the live conversation and admitted evidence. | move, opener, conversation message, prepared reply, script |
| Placement | Where in-context feedback belongs: DIFF names an admitted observation and citation for server-resolved coordinates; ARTIFACT stays at summary level. | model-authored path, model-authored line number |
| Thread key | The identity of one continuing conversation about one thing with one person on one channel. | correlation key, idempotency key |
| Supersession | Replacing a queued, still-unread message with a newer one on the same thread. | edit, update, delete |
Withhold and suppress are two different refusals and must never be merged. A withhold reason
(NO_MATERIAL_CHANGE, ALREADY_SAID, BELOW_BAR) is the composer saying nothing was worth saying. A
suppression reason is the system saying it had something and refused to send it — for example, the recipient
opted out, the artifact closed, a cap was reached, or the measurement came from a backfill. Merging them makes "we had nothing to say" indistinguishable from
"we were not allowed to say it", which is the exact distinction the whole refusal vocabulary exists for.
The three channels are three levels
FeedbackChannel is not three renderers of one message. Each value is a different level of Hattie &
Timperley's model, and every name answers one question — where does this land? — because a set of names
on different axes is how three lanes drift into saying the same thing three times.
| Channel | Lands | Level | Answers | Audience |
|---|---|---|---|---|
IN_CONTEXT | on the work artifact — pull request summary or inline note, issue comment | task | "what is worth changing or reinforcing here?" | public — the team reads it on the work |
IN_APP | on the developer's own practice pages | process | "what keeps happening in how I work?" | private — the developer alone |
IN_CHAT | in a turn of a conversation, wherever it runs — the in-app mentor at /w/:slug/mentor, or Slack | self-regulation | "what capability could this conversation support?" | private — a live mentor turn |
IN_CHAT is defined by being dialogic, IN_APP by being the non-dialogic practice surface. The
mentor renders inside the app as well, so "in the app" cannot be the test: IN_CHAT is a turn the
developer can answer, and IN_APP is written down, where reading it is the whole interaction. Ask is it
a turn? before which screen? — a new written surface inside Hephaestus is IN_APP, and a mentor in
another chat product is still IN_CHAT.
The level is derived from the channel and never stored: there is no level column, and a stored copy
would be a second truth that can disagree. Three words are close enough to be tempting and are still
wrong. Do not write profile for IN_APP — Profile is the workspace-readable page at
/w/{workspaceSlug}/user/{username} — and
do not write reflection either: it named what the developer was meant to do rather than where the
message lands, and it is the name this lane was renamed away from
(ADR 0029).
Do not write conversation for IN_CHAT: chat.conversation_thread is a kind of work Hephaestus
reviews, not a place it delivers to. And do not describe IN_CHAT as a prepared reply; what is stored
is notes to the mentor, not words to speak.
Thread key and supersession
A thread is a chain of messages about one thing to one person on one channel, identified by a hash
(FeedbackThreadKey) rather than by prose. The longitudinal channels key on the practice, because a
habit claim is about the practice and not about one merge request; the in-context channel keys on the
artifact. thread_key is deliberately not unique: a thread is a chain of rows over time, and the
invariant that matters — at most one live PREPARED per thread — is held by a compare-and-swap.
Supersession only ever claims PREPARED feedback. Say superseded for feedback that was prepared but
replaced before anybody read it, and continued for newer feedback written beside feedback that was
already read: nothing received is ever un-said, and the newer row still records what it follows through
replaces_id. Issue reviews may edit the prior issue comment in place, so their ledger entry is retired
when that visible text is replaced. Pull request reviews do not: every new review posts a new summary,
while a retry of the same review reconciles its existing comment by marker.
How a locus moved
ObservationDelta classifies every locus in a person's window as NEW, RECURRING (still there, and
the assessment or severity moved), UNCHANGED (still there, nothing moved) or RESOLVED (was a problem,
absent from the newest run of its artifact). Use these words for how one measured locus moved between
runs, and never as a claim about a person's work in general: the comparison is per artifact, so "this
keeps happening across your work" is a claim about a practice over the window and not something the
delta can say. A strength that simply was not re-observed is not RESOLVED.
Machine names
| Concept | JSON / API | Java | Database |
|---|---|---|---|
| Practice-review AI purpose | PRACTICE_REVIEW | AgentPurpose.PRACTICE_REVIEW | PRACTICE_REVIEW |
| Automated-review policy | automatedReviewPolicy | PracticeAutomatedReviewPolicy | automated_review_policy |
| Practice binding | on | PracticeBinding | bindings |
| Model binding | AgentBinding | WorkspaceAgentBinding | workspace_agent_binding |
| Signal | signals[] | SignalName | inside bindings |
| Draft occasion | onDrafts | PracticeBinding.onDrafts | inside bindings |
| Evidence requirement | needs[] | PracticeEvidenceRequirement | inside bindings |
| Evidence stance | stance | EvidenceStance | inside bindings |
| Artifact kind | artifactKind | ArtifactKind | applies_to |
| Source display name | displayName | ArtifactSourceContract.displayName | source catalog |
| Required capture quality | requiredQuality | RequiredCaptureQuality | source catalog |
| Identity policy | identity | IdentityPolicy | source catalog |
| Automated review | automatedReview | PracticeAutomatedReview | inside automated_review_policy |
| Review mode | mode | PracticeAutomatedReviewMode | inside automated_review_policy |
| Evidence sufficiency | evidenceSufficiency | PracticeEvidenceSufficiency | inside automated_review_policy |
| Insufficient evidence action | whenEvidenceIsInsufficient | PracticeInsufficientEvidenceAction | inside automated_review_policy |
| Reason a person is needed | insufficiencyReason | PracticeEvidenceLimitation | inside automated_review_policy |
| Known limitations | knownLimitations | PracticeEvidenceLimitation | inside automated_review_policy |
| Automated review validation | automatedReviewValidation | PracticeAutomatedReviewValidation | derived API value |
| Automated review readiness | not on the HTTP API | AutomatedReviewReadinessReport | agent_job.review_readiness — its own column, not inside evidence_snapshot |
| Source readiness checks | not on the HTTP API | SourceReadinessCheck | inside agent_job.review_readiness |
| Source absence reason | inside manifest.json | SourceAbsenceReason | inside agent_job.evidence_snapshot |
| Discovery provenance | discoveredVia | DiscoveredVia | artifact_signal.discovered_via |
| Observation origin | origin | ObservationOrigin | observation.origin |
| Occurrence state | — | SignalState | artifact_signal.state |
| Source-use purpose | purpose | SourceUsePurpose | source-use decisions |
| Source absence state | supportedAbsenceStates | SourceAbsenceState | source catalog |
| Materialization | artifacts | SourceArtifact | manifest and content-addressed storage metadata |
| Practice autonomy | autonomy | PracticeAutonomy | practice.autonomy, practice_group.autonomy (both nullable) |
| Effective autonomy | autonomy.effective | EffectiveAutonomy | resolved, never stored |
| Autonomy source | autonomy.source | AutonomySource | resolved, never stored |
| Workspace default autonomy | defaultAutonomy | PracticeAutonomy | workspace.practice_default_autonomy |
| Review coverage | reviewScope | WorkspaceReviewScope | workspace coverage modes plus repository/member target tables |
| Delivery status | deliveryStatus | PracticeDeliveryStatus | workspace.practice_delivery_status |
| Rollout revision | revision | long | workspace.practice_rollout_revision |
| Coverage repository mode | repositoryMode | ReviewRepositoryMode | workspace.practice_repository_coverage_mode |
| Coverage person mode | personMode | ReviewPersonMode | workspace.practice_person_coverage_mode |
| Delivery policy evaluation | deliveryPolicy[] on the trace | DeliveryPolicyEvaluation | delivery_policy_evaluation |
| Delivery policy check | checks[].check | DeliveryPolicyCheck | inside delivery_policy_evaluation.checks |
| Delivery policy check status | checks[].status | DeliveryPolicyCheckStatus | inside delivery_policy_evaluation.checks |
| Delivery policy stage | stage | DeliveryPolicyStage | delivery_policy_evaluation.stage |
| Delivery policy surface | surface | DeliveryPolicySurface | delivery_policy_evaluation.surface |
| Feedback channel | channel | FeedbackChannel | feedback.channel |
| Feedback suppression reason | suppressionReason | FeedbackSuppressionReason | feedback.suppression_reason |
| Composed feedback unit | not on the HTTP API | ComposedFeedbackUnit | never stored as such — parsed from out/feedback.json |
| Composer action | inside out/feedback.json | ComposedFeedbackUnit.Action | not stored |
| Withhold reason | inside out/feedback.json | ComposedFeedbackUnit.WithholdReason | not stored |
| Conversation move | not on the HTTP API | ConversationBriefBody | JSON inside feedback.body |
| Thread key | not on the HTTP API | FeedbackThreadKey | feedback.thread_key (not unique) |
| What a message follows | not on the HTTP API | — | feedback.replaces_id |
| Locus movement | inside inputs/history/delta.json | ObservationDelta.Status | derived, never stored |
| Signal refusal reason | — | SignalStateReason | artifact_signal.state_reason |
| Group dashboard visibility | visibleInPracticeDashboards | PracticeGroup.visibleInPracticeDashboards | visible_in_practice_dashboards |
| Claim currentness | claimCurrentness | ReviewClaimCurrentness | derived API value |
| Review-rule fingerprint | reviewRuleFingerprint | ReviewRuleFingerprint | review_rule_fingerprint |
The contract uses stable uppercase values. Author-facing UI combines the implementation fields into one mentoring choice:
LANGUAGE_MODEL+SUFFICIENT_WHEN_REQUIREMENTS_MET→ AI-supported mentoringLANGUAGE_MODEL+DECLARED_EVIDENCE_INSUFFICIENT→ Human review neededNONE+NONE→ Guidance only
Source states
Availability, content, completeness, and collection outcome are four separate facts about one capture, never one field. The artifact-source contract defines them and the states each may take; write about a capture in its words, and in particular do not write that a capture is stale — there is no such state, and the contract says why.
Outcome states
Three distinctions carry the whole weight of reading the observation table as behaviour. Do not conflate them.
| Generation outcome | Meaning | Result |
|---|---|---|
NO_REVIEW_OCCASION | The practice's prerequisite situation did not occur in this work. | An observation, normalized to durable Presence.NOT_APPLICABLE; requires evidence.exclusion. |
INSUFFICIENT_EVIDENCE | The situation occurred and available evidence was read, but it did not decide the question. | An observation, normalized to durable Presence.INCONCLUSIVE; requires evidence.missingEvidence. |
| Readiness refusal | A required source was unavailable, stale, partial, redacted, errored, or empty where content was required. | A readiness decision on the review; no observation. |
The generation values are the only choices offered by report_observation; the Presence values are
storage and read-projection vocabulary. NO_REVIEW_OCCASION is not a fallback for uncertainty: its
exclusion must name the subject and the fact about this work that rules it out. Likewise,
INSUFFICIENT_EVIDENCE cannot hide collection failure: missingEvidence names the open question and
the existing evidence that would settle it. Both shapes are enforced in the sandbox and again during
server admission.
Lifecycle
- A practice author chooses AI-supported mentoring, Human review needed, or Guidance only.
- For AI-supported mentoring, the occasion's recommended evidence is applied automatically; an author customizes it only when that occasion needs different evidence or limitations. Reading different evidence at a different moment is a second practice, not a second occasion.
- Only AI-supported mentoring can be reviewed. The other choices force the practice autonomy to
OFFand never start an automated review. - An instance operator authorizes each source and product use through a reviewed governance decision.
- A workspace integration makes authorized sources available.
- A workspace administrator sets repository and member coverage, delivery status, and the workspace default autonomy, then overrides autonomy per group or practice only where the default is wrong.
- Each review captures evidence and records explicit source states.
- Source readiness checks decide whether every required source meets its requirements.
- Hephaestus reviews the work or records that the practice was skipped.
- Observations retain the exact practice revision, source contract, and evidence provenance.
- Practice or source-contract changes move the review-rule fingerprint, so earlier claims derive as stale. Nothing marks a claim stale by hand.
- Automated review validation — always
AUTHOR_DECLARED— is separate from source authorization, practice autonomy, and per-run readiness.
Writing rules
- Name the actor: “Hephaestus reviews the work,” not “the practice is detectable.”
- Name the outcome: “skip automated review,” not “return not applicable.”
- Use provider terms when known: pull request, merge request, issue, or Slack thread.
- Put stable reason codes in machine fields and plain explanations in UI messages.
- Prefer short names only when they remain unambiguous.
- Use AI-supported mentoring for the product promise and practice review for the bounded operation.
- Describe autonomy as release authority, never as loudness or reach. It does not affect the public Profile page.
- Never write bare binding. Two unrelated things carry the word — a practice binding (an occasion
a practice is reviewed on,
PracticeBinding) and a model binding (a workspace's AI model for a purpose,WorkspaceAgentBinding) — and they send an operator to different screens. A reason code, label, or javadoc that says only "binding" has already lost that distinction, which is why the reason code for a missing AI model isREVIEW_MODEL_UNBOUNDand names the thing it means.