Summary
The git-client push feedback (GitClientUtils.buildValidationSummary) prints one line per internal validation
step, in pipeline order, regardless of whether a developer can act on it. As more checks land (trailer policy,
PII scanning split across commit messages and diff content) the list is getting long and mixes several different
audiences into one undifferentiated stream.
Problems observed
- Closely related checks report separately when a developer only cares about the combined result — "Scanning
commit messages for PII/identifiers" and "Scanning diff for PII/identifiers" could be one "Scanning for
PII/identifiers" line. Same pattern on email policy: author, committer, and trailer email checks report as
three lines when what a developer cares about is whether email policy as a whole passed.
- Some checks reveal defense surface to a client that doesn't need to know it exists in order to act on a
rejection. "Checking branch" (empty-branch detection) and "Checking for hidden commits" (pack inspection for
hidden objects) currently print PASS on every push — telling any client, hostile or not, that fogwall does this
deep inspection even when nothing was found.
- Some real signals aren't surfaced at all today — LFS disabled/detected, push options — so a developer has no
way to tell those happened.
Competing signal
Developer feedback on the current flat list has been positive independent of this issue: seeing every check run
gives developers confidence they aren't pushing something they shouldn't. Any redesign has to keep that — the
"don't reveal defense surface" point above is about a hostile client, not about withholding information from a
legitimate developer on a normal push. A design that hides passing checks from everyone to avoid tipping off an
attacker would trade away a feature developers already value. Whatever grouping ships needs to preserve "I can
see fogwall is checking for X" for the checks a developer would want reassurance about, and reserve silence (or
grouping) for checks that are purely internal defense-in-depth with no developer-facing meaning even on failure.
Wanted
A structure organized around what's actionable to a developer rather than one line per internal step, roughly:
- policy rejections — things a developer caused and can fix (email policy, trailers, commit message content)
- permission rejections — URL rules, user permission
- git-level anomalies / unsupported payload — hidden commits, empty branch, malformed pack; still reported to
the developer on failure (see Competing signal above) — the open question is whether pass-through visibility is
worth the defense-surface disclosure to a hostile client, not whether a rejection is explained
- hierarchical rather than flat — closely related sub-checks collapse into one line when all pass, and expand
into detail only on failure
Boundaries
- Client-facing summary text only (
GitClientUtils.buildValidationSummary). The dashboard push detail view and
audit trail already show every step individually and are unaffected.
- No committed design yet — this issue is to work out the grouping/hierarchy, not a spec to implement as written.
Summary
The git-client push feedback (
GitClientUtils.buildValidationSummary) prints one line per internal validationstep, in pipeline order, regardless of whether a developer can act on it. As more checks land (trailer policy,
PII scanning split across commit messages and diff content) the list is getting long and mixes several different
audiences into one undifferentiated stream.
Problems observed
commit messages for PII/identifiers" and "Scanning diff for PII/identifiers" could be one "Scanning for
PII/identifiers" line. Same pattern on email policy: author, committer, and trailer email checks report as
three lines when what a developer cares about is whether email policy as a whole passed.
rejection. "Checking branch" (empty-branch detection) and "Checking for hidden commits" (pack inspection for
hidden objects) currently print PASS on every push — telling any client, hostile or not, that fogwall does this
deep inspection even when nothing was found.
way to tell those happened.
Competing signal
Developer feedback on the current flat list has been positive independent of this issue: seeing every check run
gives developers confidence they aren't pushing something they shouldn't. Any redesign has to keep that — the
"don't reveal defense surface" point above is about a hostile client, not about withholding information from a
legitimate developer on a normal push. A design that hides passing checks from everyone to avoid tipping off an
attacker would trade away a feature developers already value. Whatever grouping ships needs to preserve "I can
see fogwall is checking for X" for the checks a developer would want reassurance about, and reserve silence (or
grouping) for checks that are purely internal defense-in-depth with no developer-facing meaning even on failure.
Wanted
A structure organized around what's actionable to a developer rather than one line per internal step, roughly:
the developer on failure (see Competing signal above) — the open question is whether pass-through visibility is
worth the defense-surface disclosure to a hostile client, not whether a rejection is explained
into detail only on failure
Boundaries
GitClientUtils.buildValidationSummary). The dashboard push detail view andaudit trail already show every step individually and are unaffected.