fix(do178): text-mode summary no longer prints a negative GAP count - #87
Merged
Merged
Conversation
checkSourceCode() refines the Evidence/Gap text for A-2.4 and A-3.1, but both objectives already come out of Assess() as StatusManual (their allObjectives entry has an empty evidence file, so they take the "manually assessed" branch and are already counted in rep.Manual). The refinement code assumed they had instead been counted as StatusGap, so it unconditionally decremented rep.Gap (A-2.4) and unconditionally incremented rep.Manual again (both), double-counting Manual and driving Gap negative whenever .fusa.json and/or all 4 plan docs were present — exactly the "-1 GAP" reported in #86, where the JSON renderer (which derives its counts by walking rep.Objectives) stayed consistent while the text renderer's rep.Gap/rep.Manual fields did not. Since obj.Status never actually changes in this function, drop the counter mutations entirely and only update the Evidence/Gap narration. Closes #86 Signed-off-by: SoundMatt <matt@jellybaby.com> Signed-off-by: Matt Jones <47545907+SoundMatt@users.noreply.github.com>
| func TestSummaryCounters_MatchObjectives_Issue86(t *testing.T) { | ||
| dir := t.TempDir() | ||
| // Trigger the A-2.4 refinement: .fusa.json present. | ||
| if err := os.WriteFile(filepath.Join(dir, ".fusa.json"), []byte("{}"), 0o644); err != nil { |
| } | ||
| // Trigger the A-3.1 refinement: all 4 plan docs present. | ||
| for _, f := range []string{"SAFETY_PLAN.md", "SVP.md", "SCMP.md", "SQAP.md"} { | ||
| if err := os.WriteFile(filepath.Join(dir, f), []byte("x"), 0o644); err != nil { |
| func TestSummary_NoNegativeGap_AllEvidencePresent_Issue86(t *testing.T) { | ||
| dir := t.TempDir() | ||
| // .fusa.json triggers the A-2.4 refinement. | ||
| if err := os.WriteFile(filepath.Join(dir, ".fusa.json"), []byte("{}"), 0o644); err != nil { |
| // Every file-based-evidence objective applicable at DAL-D, satisfied — | ||
| // so the real GAP count is zero. | ||
| wfDir := filepath.Join(dir, ".github", "workflows") | ||
| if err := os.MkdirAll(wfDir, 0o755); err != nil { |
| "sas.md": "x", | ||
| } | ||
| for f, content := range files { | ||
| if err := os.WriteFile(filepath.Join(dir, f), []byte(content), 0o644); err != nil { |
| t.Fatalf("write %s: %v", f, err) | ||
| } | ||
| } | ||
| if err := os.WriteFile(filepath.Join(wfDir, "ci.yml"), []byte("ci"), 0o644); err != nil { |
|
|
||
| // negativeCount matches a negative integer preceded by a space, e.g. " -1", | ||
| // as would appear in a malformed "Summary: ... -1 GAP ..." line. | ||
| var negativeCount = regexp.MustCompile(` -\d`) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
gofusa do178's text-mode summary line derives its GAP/MANUAL counts fromrep.Gap/rep.Manual, whichcheckSourceCode()was corrupting: A-2.4 and A-3.1 are always assessed asStatusManualbyAssess()(theirallObjectivesentry has an empty evidence file), so they're already counted inrep.ManualbeforecheckSourceCoderuns. That function wrongly assumed they'd instead been counted asStatusGap, so it unconditionally decrementedrep.Gap(for A-2.4) and unconditionally re-incrementedrep.Manual(for both), double-counting Manual and driving Gap negative whenever.fusa.jsonand/or all 4 plan docs were present — exactly the "-1 GAP" reported in do178: text-mode summary line prints negative GAP count (-1 GAP) on DAL-B report #86.satisfied/partial/gapsby walkingrep.Objectivesdirectly rather than trusting the separately-maintained counters.obj.Statusnever actually changes incheckSourceCode(both objectives stayStatusManual), drop the counter mutations entirely and only update the Evidence/Gap narration text.Closes #86
Test plan
TestSummaryCounters_MatchObjectives_Issue86, which assertsrep.Pass/Fail/Gap/Manual/NAmatch a manual walk ofrep.Objectives, and that the text renderer's enumeratedGAP/MANUALline counts agree with the header — fails pre-fix (gap=25vs26enumerated,manual=9vs7enumerated), passes post-fix.TestSummary_NoNegativeGap_AllEvidencePresent_Issue86, an exact repro: DAL-D project with every applicable evidence file present (zero real gaps) — pre-fix this reportsrep.Gap = -1(reproducing the issue's literal symptom); post-fix reports0 GAP.go build ./...,go vet ./...,golangci-lint run ./...,go test ./... -coverall clean (verified in a fresh worktree to exclude unrelated pre-existing untracked scratch files in this checkout).