Skip to main content

Flow Insights Profile

The flow-insights profile proves that a stack can infer the six canonical MVP flow insight signals from normalized provider adapter inputs, produce human-readable explanations and recommended next actions, and maintain semantic equivalence across GitHub and GitLab normalized inputs.

Why it exists​

The MVP depends on consistent interpretation across multiple providers, multiple implementation stacks, and multiple transport surfaces. Without shared scenarios and expected outcomes, implementations will drift even when each local implementation appears correct. This profile makes semantic drift visible and unacceptable across stacks.

Layer 1 spec​

Source: tests/features/flow-insights.feature

Scenarios (16 total)​

Provider-neutral core scenarios​

These six scenarios define the canonical signal semantics regardless of provider. They are provider-neutral and must pass for any conforming stack.

ScenarioWhat is checked
Blocked on review is surfaced with contextawaiting_review change past expected window; explanation names reviewers; action targets reviewers
Passed checks but failing trunk integration is highlightedBranch passed, trunk failed; explanation contrasts both; action is remediate or roll back
Unclear ownership is flagged for resolutionOwnership unclear; explanation lists conflicting owners; action confirms single owner
Waiting on evidence, not effort, is differentiatedEvidence pending; explanation lists missing items; action is supply evidence
Aging work between implementation and validation is exposedTrunk validation pending past expected window; explanation cites delay
Risk is aggregated by service from clustered signalsThree signals in 48 hours for one service; explanation aggregates contributing signals

Provider-specific scenarios​

ScenarioTagWhat is checked
GitHub blocked on review via CODEOWNERS reviewer identity@githubNamed reviewers from CODEOWNERS; action targets them by name
GitLab blocked on review via approval threshold not met@gitlabApproval count 0 of required 2; explanation reflects threshold
GitLab self-managed blocked on review with partial identity@gitlab-self-managedis_partial: true on review state; confidence reduced
GitHub trunk failure after clean Checks API pass@githubChecks API passed, trunk failed; explanation references both
GitLab trunk failure after passing MR pipeline@gitlabMR pipeline passed, trunk pipeline failed
Ownership ambiguity with two conflicting teams@githubTwo CODEOWNERS entries; explanation names both teams
GitHub waiting on evidence with identified responsible actor@githubEvidence pending; actor named in explanation
GitLab waiting on evidence with group ownership@gitlabCompliance attestation pending; group owner context
Reduced confidence from partial data@githubis_partial: true on review state reduces confidence to medium or lower

Cross-provider equivalence scenarios​

ScenarioTagWhat is checked
Blocked on review inferred equivalently from GitHub and GitLab@cross-providerSame signal id, same severity intent, same confidence tier

Cross-stack equivalence rules​

These rules are enforced by the Layer 2 harness. They apply to every implementation stack that declares capabilities.flowInsights.enabled = true.

Required to be equivalent across stacks​

  • Signal identity: the same id value must be returned for the same inferred condition (e.g., blocked_on_review).
  • Severity / priority intent: if blocked_on_review is high, it must be high across all stacks.
  • Confidence behavior: the same inputs must produce the same confidence tier. Partial inputs (is_partial: true) must reduce confidence on all stacks.
  • Recommended-action intent: the action category must be equivalent across stacks. "Notify reviewers" and "ping assigned reviewers" are equivalent. "Close the change" is not equivalent to "notify reviewers" for a blocked_on_review signal.

Not required to be identical​

  • Exact wording of explanation — semantic content must match; phrasing may differ.
  • Exact wording of recommendedNextAction — intent must match; wording may vary.
  • Ordering of signals when multiple are returned.
  • Incidental metadata fields not explicitly part of the contract.

Allowed differences​

Provider capability gaps may cause GitHub and GitLab to produce slightly different signal shapes for the same scenario. Any such difference must be documented in this section.

SignalProviderAllowed differenceReason
blocked_on_reviewGitLab self-managed (pre-14.x)confidence: medium instead of highReviewer identity is is_partial: true when the API version does not expose individual reviewer assignments

Fixture catalog​

All fixtures are in schema/fixtures/provider-adapter-input/. The table below maps each fixture to its targeted signal and provider.

Fixture fileSignalProvider
blocked-on-review-github.yamlblocked_on_reviewGitHub
blocked-on-review-gitlab.yamlblocked_on_reviewGitLab SaaS
blocked-on-review-gitlab-self-managed.yamlblocked_on_reviewGitLab self-managed
trunk-integration-failed-github.yamltrunk_integration_failureGitHub
trunk-integration-failed-gitlab.yamltrunk_integration_failureGitLab SaaS
unclear-ownership-github.yamlunclear_ownershipGitHub (no owners)
unclear-ownership-ambiguous-github.yamlunclear_ownershipGitHub (two conflicting teams)
unclear-ownership-gitlab.yamlunclear_ownershipGitLab SaaS
waiting-on-evidence-github.yamlwaiting_on_evidenceGitHub
waiting-on-evidence-gitlab.yamlwaiting_on_evidenceGitLab SaaS
aging-implementation-github.yamlaging_implementationGitHub
aging-implementation-gitlab.yamlaging_implementationGitLab SaaS
risk-aggregation-github.yamlrisk_aggregationGitHub
risk-aggregation-gitlab.yamlrisk_aggregationGitLab SaaS
partial-data-github.yamlpartial_evidenceGitHub (partial data)
changes-requested-github.yamlchanges_requestedGitHub
review-not-required-github.yamlreview_not_requiredGitHub

Layer 2 harness​

Source: tests/src/profiles/flow-insights.ts

The TypeScript harness is derived from the .feature file above. When they disagree, the .feature file is authoritative (ADR-0009).

Stack declarations​

Stacks that expose the flow insights capability must declare both the profile and the capability flag in stack.json:

{
"contractProfiles": ["core", "operational", "flow-insights"],
"capabilities": {
"flowInsights": {
"enabled": true
}
}
}

Cross-stack equivalence harness​

The flow-insights profile pairs with a cross-stack equivalence harness that boots both BFFs together, captures /api/flow/insights signal summaries for every fixture against each stack, and diffs the two captures under the equivalence rules above. The harness is invoked as make check-flow-insights-equivalence and is gated as a required PR check.

See Cross-Stack Equivalence for the full methodology, allow-list policy, and guidance for reading a failed run.