Esc
↑↓ to move↵ to openEsc to close

DocsConfiguration

Reference

Every rule kind, setting and default, generated from the schemas.

Generated from schemas

Rules (org_rules.schema.json)

Version: 5.3

How an organisation manages its code, as flat typed rules (kind + match + value). Orgs may write any number of rules, but the compiler always reduces them to the fixed column set in x-riffle-model-columns. Undeclared means null, never 0. Adding a column is a schema version bump, a retrain, and a decision record. Rules are read point-in-time from git history of the rules file, and the compiled hash is pinned into model_version. Read from the default branch only; an invalid file keeps the last valid compiled rules and posts a notice. Org file: riffle/rules.yml in the org's .github repo. Repo file: .github/riffle/rules.yml, appended after org rules and limited to that repo.

Fields every rule accepts

KeyAllowedDefaultFlagsMeaning
idstring matching ^[a-z0-9][a-z0-9-]{0,63}$
kindstring
applies_to.reposlist of string["*"]
applies_to.pathslist of stringLimit to a monorepo package, e.g. packages/react-native/**
applies_to.brancheslist of string
priorityinteger 0–10050Conflict resolution: higher wins, then the more specific glob, then the later rule.
enabledbooleantrue
notestring

Rule kinds

path_tier

Sink: feature
Compiles to: max_criticality, frac_lines_in_critical

FieldAllowedDefaultRequiredMeaning
matchstringrequired
valuelow, normal, elevated, criticalrequired

path_class

Sink: feature | filter
Compiles to: effective_lines_changed, test_lines_ratio, docs_only, config_only

FieldAllowedDefaultRequiredMeaning
matchstringrequired
valueexcluded, vendored, generated, lockfile, test, test_fixture, docs, config, build_config, dependency_manifest, i18nrequired

sensitivity

What the code handles. Split from change_signal so authn and authz stay distinct.

Sink: feature
Compiles to: n_sensitivity_tags

FieldAllowedDefaultRequiredMeaning
matchstringrequired
valueauthn, authz, payments, pii, secrets, crypto, infra, public_apirequired

change_signal

Risky change types. Handled by the extractor's own path rules too; these declarations override its defaults per repo.

Sink: feature
Compiles to: sharpens extractor touches_* features; no new columns

FieldAllowedDefaultRequiredMeaning
matchstringrequired
valueschema_migration, wire_protocol, infra_as_code, build_system, dependency_bump, feature_flag, concurrency, native_interop, release_configrequired

component

Names a monorepo package or module. The name is free text, but the model only sees generic stats computed per component from history.

Sink: feature
Compiles to: n_components_touched, max_criticality, max_exposure, max_data_class, regulated_scope_count, log_max_blast_radius, touches_deprecated

FieldAllowedDefaultRequiredMeaning
matchstringrequirede.g. streams/** or packages/virtualized-lists/**
valuestring matching ^[a-z0-9][a-z0-9-]{0,63}$required
tierinteger 1–4Availability tier, 1 is most critical
exposureinternal, partner, external
data_classpublic, internal, confidential, restricted
regimeslist of pci, gdpr, hipaa, sox, soc2, fedramp
lifecycleexperimental, active, stable, deprecated
blast_radiusinteger 0–Declared downstream dependents

owner

Path ownership. import_codeowners reads CODEOWNERS instead of listing paths.

Sink: feature
Compiles to: author_is_owner, owning_teams_touched (extractor, not a declared column)

FieldAllowedDefaultRequiredMeaning
matchstringrequiredPath glob, or the CODEOWNERS path when import_codeowners is true
valuestringrequiredTeam or login, e.g. @apache/kafka-streams
import_codeownersbooleanfalse

policy

Team policies checked against the diff. Each firing policy adds one to policy_violations; the specific policy is shown in the comment, not given its own column.

Sink: feature
Compiles to: policy_violations, required_tests_missing

FieldAllowedDefaultRequiredMeaning
matchstringrequiredPath glob the policy covers
valuerequired_tests, high_scrutiny, perf_critical, no_import_from, flag_required, migration_reversible, migration_no_destructive, dependency_allowlist, dependency_denylist, regen_pairrequired
targetstring or list of stringno_import_from: forbidden path glob. dependency_*: package names. regen_pair: generated path glob.
testsstringrequired_tests: test glob that satisfies it; defaults to path_class test
languageslist of java, python, typescript, javascript, go, kotlinno_import_from only: languages to parse imports for. Others are skipped, and the feature is null for files in them

Phase notes: no_import_from v1 for listed languages via tree-sitter import queries; other languages later; flag_required later: heuristic on known flag SDK calls only

freeze_window

Declared code freeze. days_to_freeze_start is left to the extractor.

Sink: feature
Compiles to: in_freeze_window

FieldAllowedDefaultRequiredMeaning
startstring (date-time)required
endstring (date-time)required
matchstring"*"Branch glob

pr_label

Maps PR labels at open time. Different from issue_label, which is about linked issues.

Sink: feature
Compiles to: label_priority, label_is_hotfix, label_security

FieldAllowedDefaultRequiredMeaning
matchstringrequiredExact PR label name
valuepriority, hotfix, security, saferequired
levelinteger 0–3priority only: 3 is highest (P0)

safe_change

Which change kinds this team treats as safe. No match; the extractor classifies lines.

Sink: feature
Compiles to: is_safe_change_only

FieldAllowedDefaultRequiredMeaning
valuedocs, tests, formatting, comments, generated, i18nrequired

pattern

Sink: label | feature
Compiles to: task_type, is_backport, labels: revert, bugfix

FieldAllowedDefaultRequiredMeaning
matchstring (regex)required
valuerevert, bugfix, hotfix, backport, conventional_type, security_fixrequired
fieldcommit_message, commit_trailer, pr_title, pr_body, branch_name"commit_message"

Connects objects Riffle would otherwise treat as unrelated. match must contain a named group (?<ref>...).

Sink: link
Compiles to: commit-PR-issue graph used by every label source; cherry picks dedupe labels across branches

FieldAllowedDefaultRequiredMeaning
matchstring (regex)required
fieldcommit_message, commit_trailer, pr_title, pr_body"commit_trailer"
valuepr_ref, revert_target, cherry_pick_source, issue_key, external_change_idrequired
trackerstring matching ^[a-z0-9][a-z0-9-]{0,63}$For issue_key: which sources.trackers entry

identity

Recovers the real person when a bot lands the commit or email differs from login. match needs a named group (?<login>...) or (?<email>...).

Sink: feature
Compiles to: author_* features use the resolved author, reviewer_count, reviewer_path_experience

FieldAllowedDefaultRequiredMeaning
matchstring (regex)required
oncommit_trailer, commit_message, pr_body, co_authored_by"commit_trailer"
valueauthor, co_author, reviewer, landerrequired

merge_signal

What counts as merged. Needed when PRs are closed and the change lands another way.

Sink: label
Compiles to: merged_at, merge_commit_sha for every outcome window

FieldAllowedDefaultRequiredMeaning
valuegithub_merge, linked_commit_on_default, bot_close_with_commit, direct_pushrequired
matchstring"*"Actor login for bot_close_with_commit, else '*'

issue_field

Tracker fields beyond labels, e.g. Jira issuetype and priority.

Sink: label

FieldAllowedDefaultRequiredMeaning
trackerstring matching ^[a-z0-9][a-z0-9-]{0,63}$required
fieldstringrequirede.g. issuetype, priority, customfield_10020
matchstringrequired
valuebug, incident, regression, security, not_a_bugrequired
severityinteger 1–41 is worst; scales label weight

issue_label

Sink: label

FieldAllowedDefaultRequiredMeaning
trackerstring matching ^[a-z0-9][a-z0-9-]{0,63}$"github"
matchstringrequired
valuebug, incident, regression, security, not_a_bugrequired
severityinteger 1–4

author_class

Sink: feature
Compiles to: agent_in_critical, author_is_maintainer, author_is_external, author_is_new (extractor)

FieldAllowedDefaultRequiredMeaning
matchstringrequired
onlogin, email_domain, branch_prefix, commit_trailer"login"
valuebot, agent, maintainer, employee, externalrequired
new_contributor_daysinteger 1–730Optional; overrides the default tenure cut for authors this rule matches

ci_check

Sink: feature | label
Compiles to: ci_required_failed, ci_failures_non_flaky, label: post_merge_ci

FieldAllowedDefaultRequiredMeaning
sourcestring matching ^[a-z0-9][a-z0-9-]{0,63}$sources.ci entry; default is GitHub checks
matchstringrequired
valuerequired, flaky, informational, auxiliaryrequiredauxiliary (CodeQL, Scorecards, coverage) never triggers ci_fail
stagepre_merge, post_merge, nightly, release"pre_merge"

test_class

Test-level flakiness from sources.test_reports, for repos with one giant CI check.

Sink: feature | label
Phase: later

FieldAllowedDefaultRequiredMeaning
matchstringrequiredTest id glob, e.g. org.apache.kafka.streams.integration.*
valueflaky, quarantined, slowrequired

label_source

Weight of an outcome source as a sample weight in this org's per-repo layer. Never applied to the global model. Windows: revert 30d, ci_fail on required checks only, hotfix is a hotfix-labelled PR on the same lines within 7d, follow_up_fix is any PR on the same lines within 14d.

Sink: label

FieldAllowedDefaultRequiredMeaning
matchrevert, ci_fail, hotfix, szz, follow_up_fix, route_override, incident_link, external_importrequired
valuenumber 0–2required
window_daysinteger 1–90

branch_class

Sink: feature | label
Compiles to: targets_release_branch

FieldAllowedDefaultRequiredMeaning
matchstringrequired
valuedefault, release, hotfix, backport, long_lived, experimentalrequired

stack

Stacked PR tooling, so a stack is understood as related changes.

Sink: feature
Compiles to: stack_depth, stack_position

FieldAllowedDefaultRequiredMeaning
valueghstack, graphite, sapling, spr, branch_chainrequired
matchstringrequiredBranch pattern or body marker the tool leaves

sources block

KeyAllowedDefaultFlagsMeaning
sources.trackerslist of objects
sources.trackers[].idstring matching ^[a-z0-9][a-z0-9-]{0,63}$
sources.trackers[].providergithub, jira, linear, bugzilla, youtrack
sources.trackers[].base_urlstring (uri)
sources.trackers[].projectslist of string
sources.trackers[].credentials_refstring
sources.cilist of objects
sources.ci[].idstring matching ^[a-z0-9][a-z0-9-]{0,63}$
sources.ci[].providergithub_checks, commit_status, external_apicommit_status covers Jenkins, Buildkite and anything posting legacy statuses
sources.ci[].context_globstring"*"
sources.ci[].credentials_refstring
sources.test_reports.enabledbooleanfalselater
sources.test_reports.formatjunit_xml"junit_xml"later
sources.test_reports.artifact_globstring"**/TEST-*.xml"later
sources.outcome_import.enabledbooleanfalse
sources.outcome_import.secret_refstring

labels block

KeyAllowedDefaultFlagsMeaning
labels.targetunion, weighted"union"union: label_bad = any target source fires (binary). weighted: each source's label_source weight becomes a sample weight. Per-repo layer only
labels.szz_in_targetbooleanfalseSZZ stays a separate label unless true
labels.maturity_daysinteger 7–18030Rows younger than this are dropped before training (label_mature)
labels.szz_maturity_daysinteger 30–36590
labels.unobservedmask, negative, downweight"downweight"What to do when a label source had no data for a mature PR (e.g. CI results expired). Any observed source that fired still makes the row positive. Otherwise: mask drops the row; negative counts it as fully clean; downweight counts it as clean with sample weight unobserved_weight
labels.unobserved_weightnumber 0.05–10.5downweight only. Multiplies the row's sample weight for each unobserved source (0.5 with one missing, 0.25 with two)
labels.target_sourceslist of revert, ci_fail, hotfix, szz, follow_up_fix, route_override, incident_link, external_import["revert", "ci_fail", "hotfix"]Sources that can make a row positive. Others still get mined and reported as ablations, but do not enter the target

mining block

KeyAllowedDefaultFlagsMeaning
mining.similar_prs.kinteger 3–205
mining.similar_prs.min_file_overlapnumber 0.05–10.2Jaccard over touched files
mining.similar_prs.lookback_daysinteger 30–1095365
mining.similar_prs.min_neighboursinteger 1–103Fewer than this and the feature is null
mining.scrutiny.lookback_daysinteger 30–1095180
mining.scrutiny.exclude_bot_reviewsbooleantrue
mining.scrutiny.min_prior_prsinteger 1–505
mining.failure_mode.lookback_daysinteger 90–1095365
mining.failure_mode.min_bad_changesinteger 1–202
mining.path_size.lookback_daysinteger 30–1095365
mining.path_size.min_prior_changesinteger 3–10010
mining.release_cycle.tag_patternstring (regex)"^v?\\d+\\.\\d+(\\.\\d+)?$"Which tags count as releases, e.g. ^\d+.\d+.0$ for minor releases only
mining.release_cycle.min_releasesinteger 2–203
mining.release_cycle.interval_statmedian, mean"median"
mining.flaky_detection.enabledbooleantrue
mining.flaky_detection.min_rerun_passesinteger 1–203
mining.flaky_detection.lookback_daysinteger 14–36590

model block

KeyAllowedDefaultFlagsMeaning
model.per_repo_layer.enabledbooleantruefalse serves the global model only (layer_weight 0)
model.per_repo_layer.max_layer_weightnumber 0–11.0
model.disabled_featureslist of string[]unionFeature names forced to null. Width of the vector never changes. Repos may only add. Example: agent_authored
model.backfill.lookback_daysinteger 90–36501095
model.backfill.recent_first_daysinteger 30–365180

Declared model columns

Every rule compiles to these fixed columns. null when undeclared.

ColumnMeaning
max_criticality0-3 from path_tier and component tier
frac_lines_in_criticalshare of changed lines at tier critical
n_components_toucheddeclared components spanned
n_sensitivity_tagsdistinct sensitivity values touched
max_exposure0 internal, 1 partner, 2 external
max_data_class0 public, 1 internal, 2 confidential, 3 restricted
regulated_scope_countdistinct regimes touched
log_max_blast_radiuslog1p of declared dependents
touches_deprecatedany touched component has lifecycle deprecated
policy_violationscount of policy rules broken by the diff
required_tests_missinga required_tests policy fired
in_freeze_windowPR opened inside a freeze window
targets_release_branchbase branch class is release or hotfix
author_is_ownerresolved author owns any touched path
agent_in_criticalagent-authored and max_criticality = 3
label_priority0-3 from pr_label priority, null if unlabeled
is_safe_change_onlyevery changed line falls in a declared safe_change kind

Settings (org_config.schema.json)

Version: 5.0

How the app behaves. Settings never change what the model sees or learns; those live in contracts/org_rules.schema.json and are pinned into model_version. Files: .github/riffle.yml in the org's .github repo (org defaults) and in each repo. Loading: built-in defaults, then org file, then repo file (repo wins), then organization.locked_keys restored from the org file. Files are read from the default branch only, so a PR cannot change the settings it is judged by. An invalid file never stops Riffle: the last valid settings stay in force and one neutral notice is posted. Arrays replace unless marked x-riffle-merge: union. Keys marked x-riffle-org-only are ignored in repo files. Every key has a default, so a file with only schema_version is valid.

schema_version

KeyAllowedDefaultFlagsMeaning
schema_versionstring matching ^5\.[0-9]+$major.minor. Minor adds optional keys; major renames or removes, with deprecated keys accepted for one minor version

mode

KeyAllowedDefaultFlagsMeaning
modeactive, shadow, off"active"shadow scores, learns and logs but posts nothing

organization

KeyAllowedDefaultFlagsMeaning
organization.outcome_sharing.enabledbooleanfalseorg onlyAnonymised feature vectors and outcomes only. Never code, diffs or identities
organization.data_retention.store_diffsbooleanfalseorg only
organization.data_retention.retention_daysinteger 30–730365org only
organization.label_prefixstring"riffle"org only
organization.locked_keyslist of string matching ^/["/organization", "/llm/provider", "/llm/send"]org onlyJSON pointers a repo file may not change

scope

KeyAllowedDefaultFlagsMeaning
scope.base_brancheslist of string (regex)[]Extra target branches besides the default branch
scope.include_draftsbooleanfalse
scope.quiet_authorslist of string["dependabot[bot]", "renovate[bot]", "github-actions[bot]"]unionScored and shown on the dashboard, but no comment or label. Nothing is left unscored
scope.quiet_title_keywordslist of string["WIP", "DO NOT MERGE"]unionSame as quiet_authors, matched on the PR title

rank_bands

KeyAllowedDefaultFlagsMeaning
rank_bands.modepercentile, absolute"percentile"
rank_bands.percentile.senior_recommended_top_fractionnumber 0–10.05
rank_bands.percentile.review_first_top_fractionnumber 0–10.2Matches the top-20% effort-aware recall metric
rank_bands.percentile.windowrepo, component"repo"component ranks each monorepo package against itself
rank_bands.absolute.senior_recommended_min_scorenumber 0–10.8
rank_bands.absolute.review_first_min_scorenumber 0–10.5
rank_bands.holdout_fractionnumber 0.02–0.10.05Share of PRs left unranked (FIFO) to measure lift and limit feedback-loop bias
rank_bands.tie_breaklist of similar_pr_bad_rate, path_detection_lag_days, revealed_path_scrutiny, path_size_pctile, release_cycle_position["similar_pr_bad_rate", "path_detection_lag_days"]Only for identical rounded scores; PR age is always the last key

floors

KeyAllowedDefaultFlagsMeaning
floors.enabledbooleantruedecision pending
floors.pathslist of objects[]decision pending, union
floors.paths[].patternstringdecision pending, union
floors.paths[].min_bandreview_first, senior_recommendeddecision pending, unionstandard is the lowest band, so it is not a floor
floors.ai_agentsreview_first, senior_recommended or nullnulldecision pending
floors.first_time_contributorsreview_first, senior_recommended or nullnulldecision pending

size

KeyAllowedDefaultFlagsMeaning
size.thresholds.xsinteger 0–0
size.thresholds.sinteger 0–10
size.thresholds.minteger 0–100
size.thresholds.linteger 0–500
size.thresholds.xlinteger 0–1000
size.count_filesbooleanfalse
size.ignore_pathslist of string["**/*.lock", "**/package-lock.json", "**/go.sum"]Excluded from the size label only; still counted for risk
size.apply_labelbooleantrue
size.large_pr_notestring or nullnull

authors

KeyAllowedDefaultFlagsMeaning
authors.agentsfull, label_only, silent"full"silent still scores and shows on the dashboard
authors.externalfull, label_only, silent"full"silent still scores and shows on the dashboard
authors.ai_agent_labelstring or null"ai-authored"Transparency label. Detection itself is configured in rules (author_class)
authors.path_experience_notebooleantrueMention when the author rarely touches these files

reviewer_routing

KeyAllowedDefaultFlagsMeaning
reviewer_routing.modeoff, suggest, request"suggest"
reviewer_routing.use_codeownersbooleantrue
reviewer_routing.senior_reviewerslist of string matching ^@[A-Za-z0-9-]+(/[A-Za-z0-9._-]+)?$[]
reviewer_routing.groupslist of objects[]
reviewer_routing.groups[].namestring
reviewer_routing.groups[].pathslist of string
reviewer_routing.groups[].reviewerslist of string matching ^@[A-Za-z0-9-]+(/[A-Za-z0-9._-]+)?$
reviewer_routing.reviewers_per_printeger 1–51
reviewer_routing.algorithmload_balance, round_robin, random"load_balance"
reviewer_routing.max_open_reviews_per_reviewerinteger or null 1–null
reviewer_routing.skip_title_keywordslist of string["wip"]

availability

KeyAllowedDefaultFlagsMeaning
availability.users_unavailablelist of string matching ^@[A-Za-z0-9-]+(/[A-Za-z0-9._-]+)?$[]
availability.timezonestring"UTC"IANA name
availability.working_dayslist of mon, tue, wed, thu, fri, sat, sun["mon", "tue", "wed", "thu", "fri"]
availability.working_hoursstring matching ^([01][0-9]|2[0-3]):[0-5][0-9]-([01][0-9]|2[0-3]):[0-5][0-9]$"09:00-17:00"

review_targets

KeyAllowedDefaultFlagsMeaning
review_targets.senior_recommended_hoursinteger 1–7204
review_targets.review_first_hoursinteger 1–7204
review_targets.standard_hoursinteger 1–7208

reminders

KeyAllowedDefaultFlagsMeaning
reminders.enabledbooleanfalse
reminders.min_age_hoursinteger 1–72024
reminders.min_staleness_hoursinteger 1–7208
reminders.ignore_draftsbooleantrue
reminders.ignore_approved_withinteger 0–101
reminders.ignored_labelslist of string[]

rescore

KeyAllowedDefaultFlagsMeaning
rescore.onlist of push, ready_for_review, ci_completed, reopened, edited, labeled["push", "ready_for_review", "ci_completed", "reopened"]
rescore.max_rescores_per_printeger 1–10020
rescore.min_minutes_between_editsinteger 0–602

commands

KeyAllowedDefaultFlagsMeaning
commands.enabledbooleantrue
commands.prefixstring matching ^/[a-z-]+$"/riffle"
commands.override.allowedwrite_access, maintainers, codeowners"write_access"org only
commands.override.require_reasonbooleantrueorg onlyThe reason is stored with the route_override training label
commands.override.allow_downgradebooleantrueorg onlyFloors still apply
commands.disable_labelstring"riffle:disabled"Stops comments on that PR; it is still scored

pr_output

KeyAllowedDefaultFlagsMeaning
pr_output.post_commentbooleantrue
pr_output.update_existing_commentbooleantrue
pr_output.apply_labelsbooleantrue
pr_output.labels.review_firststring"review first"
pr_output.labels.standardstring"standard"
pr_output.labels.senior_recommendedstring"senior recommended"
pr_output.labels.overridestring"wrong route"
pr_output.component_label_prefixstring or nullnull
pr_output.bands_with_commentlist of review_first, standard, senior_recommended["review_first", "senior_recommended"]
pr_output.show_top_factorsinteger 0–53From SHAP; explains the rank even with the LLM off
pr_output.show_scorebooleanfalse
pr_output.show_componentbooleantrue
pr_output.collapsebooleantrue
pr_output.evidence.cite_similar_prsinteger 0–53
pr_output.evidence.failure_modebooleantrue
pr_output.evidence.scrutinybooleantrue
pr_output.evidence.path_sizebooleantrue
pr_output.evidence.release_cyclebooleantrue

explanation

KeyAllowedDefaultFlagsMeaning
explanation.enabledbooleantrueTurning off never stops scoring
explanation.languagestring matching ^[a-z]{2}(-[A-Z]{2})?$"en-US"
explanation.max_bulletsinteger 1–73
explanation.show_review_effortbooleantrue
explanation.mention_missing_testsbooleantrue
explanation.mention_missing_issuebooleanfalse
explanation.show_effective_configbooleanfalse
explanation.known_fragilelist of string[]Paths the narrator names explicitly
explanation.house_termsobject{}

llm

KeyAllowedDefaultFlagsMeaning
llm.providernone, hosted, self_hosted"none"none = SHAP template explanations only
llm.endpointstring or null (uri)null
llm.sendfeatures_only, diff_hunks, full_files"features_only"Repos may only make this stricter
llm.excluded_pathslist of string["**/.env*", "**/*.pem", "**/*.key", "**/*secret*"]union
llm.max_calls_per_hourinteger 0–1000060

queue

KeyAllowedDefaultFlagsMeaning
queue.epic_prioritybooleanfalseLinked issue priority breaks ties inside a band
queue.manual_boosts.enabledbooleanfalse
queue.manual_boosts.areaslist of objects[]
queue.manual_boosts.areas[].pathslist of string
queue.manual_boosts.areas[].boostnumber 0–0.20.05Moves queue position, never risk_score

stacks

KeyAllowedDefaultFlagsMeaning
stacks.score_aseach_pr, whole_stack"each_pr"
stacks.comment_oneach_pr, stack_top"each_pr"

limits

KeyAllowedDefaultFlagsMeaning
limits.max_comments_per_hourinteger 1–1000120

overrides

Per component or path, inside a monorepo. Most specific match wins.

Each entry has match (component or paths) and may set rank_bands, pr_output, reviewer_routing, review_targets with the same keys as the top-level blocks.

dashboard

KeyAllowedDefaultFlagsMeaning
dashboard.visibilityorg_members, repo_writers, admins"repo_writers"org only
dashboard.show_individual_metricsbooleanfalseorg onlyPer-person statistics stay hidden unless on
dashboard.group_byband, component, owner, author_type"band"org only

audit

KeyAllowedDefaultFlagsMeaning
audit.enabledbooleantrueorg only
audit.retention_daysinteger 30–1095365org only

notifications

KeyAllowedDefaultFlagsMeaning
notifications.slack_webhook_secret_refstring or nullnulllater
notifications.digestoff, daily, weekly"off"later

Code checks

Cross-field rules the schema cannot express:

  • rank_bands.percentile.senior_recommended_top_fraction <= review_first_top_fraction
  • rank_bands.absolute.review_first_min_score <= senior_recommended_min_score
  • size.thresholds strictly increase xs < s < m < l < xl
  • scope.base_branches entries compile as regex
  • repo files cannot loosen locked or privacy keys (e.g. llm.send may only move toward features_only)
  • floors never lower a band; a floor that equals the model band is not shown

Mined features (mined_features.schema.json)

Version: 1.0

Five features mined from git, CI and review history that capture how one repository behaves. Produced by the scorer's extractor at the PR's base commit, appended to the fixed feature vector, and emitted alongside evidence the narrator may cite. Point-in-time rule: only past PRs merged before this PR opened AND whose labels were mature at that moment may contribute. Only reviews completed before open count. null means not enough history (thresholds in rules.mining), never 0.

columns

KeyAllowedDefaultFlagsMeaning
columns.similar_pr_bad_ratenumber or null 0–1Share of the k nearest past PRs (Jaccard over touched files, >= min_file_overlap) with label_bad. Smoothed toward repo_revert_base_rate when neighbours are few
columns.similar_pr_countinteger 0–Neighbours actually found; lets the model discount a rate built on 3 PRs
columns.revealed_path_scrutinynumber or null 0–Mean over touched files of (review comments + 2 x changes_requested + rounds) on prior PRs, divided by the repo mean. 1.0 = typical for this repo
columns.path_failure_mode_revertnumber or null 0–1Share of past bad changes on these paths that were reverts
columns.path_failure_mode_cinumber or null 0–1Share that were post-merge CI failures
columns.path_failure_mode_hotfixnumber or null 0–1Share that were hotfixes. The three shares sum to 1 when not null. Encoded as shares, not a category, so trees can split on them
columns.path_detection_lag_daysnumber or null 0–Median days from merge to the outcome event for past bad changes on these paths. High = failures here surface slowly
columns.path_size_pctilenumber or null 0–1Percentile of this PR's LA+LD among past changes to the same files (weighted by lines per file). Complements the repo-wide pr_size_pctile_repo
columns.release_cycle_positionnumber or null 0–Days since last release tag divided by the repo's typical release interval. Above 1 means a release is overdue

evidence

KeyAllowedDefaultFlagsMeaning
evidence.similar_prslist of objects
evidence.similar_prs[].pr_numberinteger
evidence.similar_prs[].overlapnumber 0–1
evidence.similar_prs[].outcomeclean, revert, ci_fail, hotfix
evidence.similar_prs[].merged_atstring (date-time)
evidence.scrutiny_top_pathobject or null
evidence.failure_mode_topobject or null
evidence.size_contextobject or null
evidence.release_contextobject or null

Outcome import (outcome_import.schema.json)

Version: 1.0

Body of POST /v1/outcomes. Lets an org report outcomes Riffle cannot see (internal reverts, incidents, internal CI). Signed with the secret named in rules sources.outcome_import. Imported outcomes become the external_import label source, weighted by its label_source rule. Idempotent on event_id. Never carries code or diffs.

KeyAllowedDefaultFlagsMeaning
event_idstringSender's unique id; resends are ignored
repostring matching ^[A-Za-z0-9-]+/[A-Za-z0-9._-]+$
target.commit_shastring matching ^[0-9a-f]{40}$
target.pr_numberinteger 1–
target.external_change_idstringMatched through link rules, e.g. D12345678
outcomerevert, incident, ci_fail, hotfix, clean
severityinteger 1–41 is worst
occurred_atstring (date-time)
sourcestringFree label for audit, e.g. internal-ci

Riffle mined history manifest (mined_history.schema.json)

Version: 1.0

Manifest written by the Go history miner (services/miner) for one repository and one run, next to the Parquet tables it lists. pipelines/ and scorer read the tables only through this manifest. Tables are raw history, not model features: every feature is computed in Python from these tables, in training and serving alike. Data stays inside the installation; author emails are stored only as salted hashes. A run is usable only when status is complete; partial runs carry a checkpoint and are resumed, never read.

KeyAllowedDefaultFlagsMeaning
run_idstringUnique per run; reruns with the same run_id overwrite the same files (idempotent)
tenant_idstring
repostring matching ^[A-Za-z0-9-]+/[A-Za-z0-9._-]+$
miner_versionstringPinned into model_version via the feature extractor version
statusrunning, partial, complete, failed
window.fromstring (date-time)
window.tostring (date-time)
window.head_shastring matching ^[0-9a-f]{40}$Default branch head the run mined up to
started_atstring (date-time)
finished_atstring or null (date-time)
checkpointobject or nullWhere a partial or failed run resumes. Opaque to readers.
rate_limit.requestsinteger 0–
rate_limit.conditional_hitsinteger 0–304 responses, which do not count against the limit
rate_limit.secondary_limit_waitsinteger 0–
coverage.check_runs_fromstring or null (date-time)Earliest check result still retrievable; ci_fail is unobserved before this
coverage.reviews_fromstring or null (date-time)
tableslist of objects
tables[].namecommits, file_changes, pull_requests, reviews, check_runs, tags
tables[].uristringgs:// or file:// path to the Parquet file
tables[].rowsinteger 0–
tables[].sha256string matching ^[0-9a-f]{64}$

Table commits

ColumnType and meaning
shastring, primary key
parent_shaslist<string>
author_loginstring or null, resolved through identity rules
author_email_hashstring, salted per installation
committed_attimestamp
messagestring, used by pattern and link rules
is_mergebool

Table file_changes

ColumnType and meaning
shastring, commits.sha
pathstring
old_pathstring or null, set on rename
statusadded | modified | removed | renamed
lines_addedint
lines_deletedint
is_binarybool

Table pull_requests

ColumnType and meaning
numberint, primary key
author_loginstring
created_attimestamp
merged_attimestamp or null
closed_attimestamp or null
base_branchstring
head_branchstring
merge_commit_shastring or null
labels_at_openlist<string>
is_draft_at_openbool
titlestring

Table reviews

ColumnType and meaning
pr_numberint, pull_requests.number
reviewer_loginstring
stateapproved | changes_requested | commented | dismissed
submitted_attimestamp
comment_countint

Table check_runs

ColumnType and meaning
head_shastring
namestring
conclusionsuccess | failure | neutral | cancelled | skipped | timed_out | action_required | null
run_attemptint, for flaky detection
app_idint
completed_attimestamp or null

Table tags

ColumnType and meaning
namestring
shastring
created_attimestamp