Skip to content

CS-424 [Improvement] Include a default justification at all times on the SoA#2921

Open
github-actions[bot] wants to merge 10 commits into
mainfrom
chas/soa-justification
Open

CS-424 [Improvement] Include a default justification at all times on the SoA#2921
github-actions[bot] wants to merge 10 commits into
mainfrom
chas/soa-justification

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot commented May 25, 2026

This is an automated pull request to merge chas/soa-justification into dev.
It was created by the [Auto Pull Request] action.


Summary by cubic

Ensure every SoA control always has a justification by adding ISO 27001:2022 family defaults, a generic fallback when no family matches, and showing/saving them for both Applicable and Not Applicable. Addresses CS-424.

  • New Features
    • API: Added INCLUSION_JUSTIFICATIONS and getInclusionJustification (ISO 27001:2022 family mapping incl. all of section 7). When the answer is missing/insufficient or a YES lacks a reason, default to a family justification or a generic default. Pass control closure through parsing/defaults and persist justifications for both YES and NO.
    • App: Always show the justification in table and mobile views. Allow editing for both states; only require text when Not Applicable.
    • Tests: Added unit tests for getInclusionJustification family mapping.

Written for commit b9fd71b. Summary will update on new commits.

Review in cubic

@vercel
Copy link
Copy Markdown

vercel Bot commented May 25, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
app Ready Ready Preview, Comment Jun 1, 2026 8:01pm
comp-framework-editor Ready Ready Preview, Comment Jun 1, 2026 8:01pm
portal Ready Ready Preview, Comment Jun 1, 2026 8:01pm

Request Review

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 8 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

@chasprowebdev chasprowebdev changed the title [dev] [chasprowebdev] chas/soa-justification CS-424 [Improvement] Include a default justification at all times on the SoA May 25, 2026
@linear
Copy link
Copy Markdown

linear Bot commented May 25, 2026

CS-424

@chasprowebdev
Copy link
Copy Markdown
Contributor

@cubic-dev-ai please review it

@cubic-dev-ai
Copy link
Copy Markdown
Contributor

cubic-dev-ai Bot commented May 25, 2026

@cubic-dev-ai please review it

@chasprowebdev I have started the AI code review. It will take a few minutes to complete.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 8 files

Confidence score: 3/5

  • There is a concrete runtime risk in apps/api/src/soa/utils/soa-answer-parser.ts: calling trim without verifying the justification value is a string can throw on non-string JSON and break answer parsing for affected requests.
  • apps/api/src/soa/utils/constants.ts has a medium-impact fallback gap where many controls can still return null, so some YES/default flows may persist without a justification instead of a safe generic default.
  • Given the two medium-to-high severity issues (6–7/10) with strong confidence, this looks like some regression risk rather than a merge-blocker if those paths are uncommon.
  • Pay close attention to apps/api/src/soa/utils/soa-answer-parser.ts, apps/api/src/soa/utils/constants.ts - parser type-guarding and fallback defaults directly affect justification persistence reliability.

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread apps/api/src/soa/utils/soa-answer-parser.ts Outdated
Comment thread apps/api/src/soa/utils/constants.ts Outdated
@chasprowebdev
Copy link
Copy Markdown
Contributor

@cubic-dev-ai please review it

@cubic-dev-ai
Copy link
Copy Markdown
Contributor

cubic-dev-ai Bot commented May 25, 2026

@cubic-dev-ai please review it

@chasprowebdev I have started the AI code review. It will take a few minutes to complete.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 8 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

@tofikwest
Copy link
Copy Markdown
Contributor

@cubic-dev-ai review it

@cubic-dev-ai
Copy link
Copy Markdown
Contributor

cubic-dev-ai Bot commented May 26, 2026

@cubic-dev-ai review it

@tofikwest I have started the AI code review. It will take a few minutes to complete.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 8 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

@chasprowebdev
Copy link
Copy Markdown
Contributor

@cubic-dev-ai Ultrareview

@cubic-dev-ai
Copy link
Copy Markdown
Contributor

cubic-dev-ai Bot commented Jun 1, 2026

@cubic-dev-ai Ultrareview

@chasprowebdev Starting ultrareview - a deeper analysis than a regular review. I'll post findings when complete.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ultrareview completed in 10m 26s

3 issues found across 8 files

Confidence score: 3/5

  • There is a concrete user-facing data quality risk: in apps/app/src/app/(app)/[orgId]/documents/statement-of-applicability/components/EditableSOAFields.tsx, YES answers can be persisted with blank justification, which can leave incomplete SOA records.
  • Rendering/default behavior is inconsistent in apps/app/src/app/(app)/[orgId]/documents/statement-of-applicability/components/SOATableRow.tsx because ?? treats empty strings as valid, so fallback justification is skipped and users see .
  • Parser logic in apps/api/src/soa/utils/soa-answer-parser.ts accepts insufficient placeholder-like YES justifications as valid, which can prevent intended default justification fallback across API flows.
  • Pay close attention to apps/app/src/app/(app)/[orgId]/documents/statement-of-applicability/components/EditableSOAFields.tsx, apps/app/src/app/(app)/[orgId]/documents/statement-of-applicability/components/SOATableRow.tsx, and apps/api/src/soa/utils/soa-answer-parser.ts - justification validation/fallback rules are misaligned and can propagate blank or weak values.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/app/src/app/(app)/[orgId]/documents/statement-of-applicability/components/EditableSOAFields.tsx">

<violation number="1" location="apps/app/src/app/(app)/[orgId]/documents/statement-of-applicability/components/EditableSOAFields.tsx:146">
P2: YES answers can be saved without a non-empty justification, allowing blank justifications to persist.</violation>
</file>

<file name="apps/app/src/app/(app)/[orgId]/documents/statement-of-applicability/components/SOATableRow.tsx">

<violation number="1" location="apps/app/src/app/(app)/[orgId]/documents/statement-of-applicability/components/SOATableRow.tsx:80">
P2: Saved-answer justification uses `??`, so empty-string saves bypass fallback and render as `—` instead of a default justification.</violation>
</file>

<file name="apps/api/src/soa/utils/soa-answer-parser.ts">

<violation number="1" location="apps/api/src/soa/utils/soa-answer-parser.ts:188">
P2: YES justifications treat insufficient placeholder text as valid and skip fallback defaults.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment on lines +146 to +152
if (isApplicable === false && (!justification || justification.trim().length === 0)) {
setError('Justification is required when Applicable is NO');
justificationTextareaRef.current?.focus();
return;
}

await executeSave(false, justification);
await executeSave(isApplicable, justification);
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Jun 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: YES answers can be saved without a non-empty justification, allowing blank justifications to persist.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/app/src/app/(app)/[orgId]/documents/statement-of-applicability/components/EditableSOAFields.tsx, line 146:

<comment>YES answers can be saved without a non-empty justification, allowing blank justifications to persist.</comment>

<file context>
@@ -152,13 +143,13 @@ export function EditableSOAFields({
 
   const handleJustificationSave = async () => {
-    if (!justification || justification.trim().length === 0) {
+    if (isApplicable === false && (!justification || justification.trim().length === 0)) {
       setError('Justification is required when Applicable is NO');
       justificationTextareaRef.current?.focus();
</file context>
Suggested change
if (isApplicable === false && (!justification || justification.trim().length === 0)) {
setError('Justification is required when Applicable is NO');
justificationTextareaRef.current?.focus();
return;
}
await executeSave(false, justification);
await executeSave(isApplicable, justification);
const normalizedJustification = justification?.trim() ?? '';
if (isApplicable !== null && normalizedJustification.length === 0) {
setError('Justification is required');
justificationTextareaRef.current?.focus();
return;
}
await executeSave(
isApplicable,
normalizedJustification.length > 0 ? normalizedJustification : null,
);
Fix with Cubic

displayIsApplicable === false
? (answerData.answer ?? question.columnMapping.justification ?? null)
: null;
answerData.answer ?? question.columnMapping.justification ?? null;
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Jun 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Saved-answer justification uses ??, so empty-string saves bypass fallback and render as instead of a default justification.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/app/src/app/(app)/[orgId]/documents/statement-of-applicability/components/SOATableRow.tsx, line 80:

<comment>Saved-answer justification uses `??`, so empty-string saves bypass fallback and render as `—` instead of a default justification.</comment>

<file context>
@@ -77,9 +77,7 @@ export function SOATableRow({
-      displayIsApplicable === false
-        ? (answerData.answer ?? question.columnMapping.justification ?? null)
-        : null;
+      answerData.answer ?? question.columnMapping.justification ?? null;
   } else {
     // Normal logic: processedResult / column mapping until user saves (then branch above)
</file context>
Suggested change
answerData.answer ?? question.columnMapping.justification ?? null;
answerData.answer || question.columnMapping.justification || null;
Fix with Cubic

finalIsApplicable === false ? parsedAnswer.justification || null : null;
finalIsApplicable === false
? llmJustification
: llmJustification || getInclusionJustification(closure);
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Jun 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: YES justifications treat insufficient placeholder text as valid and skip fallback defaults.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/api/src/soa/utils/soa-answer-parser.ts, line 188:

<comment>YES justifications treat insufficient placeholder text as valid and skip fallback defaults.</comment>

<file context>
@@ -163,12 +170,22 @@ export function parseAndProcessSOAAnswer(
-    finalIsApplicable === false ? parsedAnswer.justification || null : null;
+    finalIsApplicable === false
+      ? llmJustification
+      : llmJustification || getInclusionJustification(closure);
 
   send({
</file context>
Suggested change
: llmJustification || getInclusionJustification(closure);
: llmJustification && !isInsufficientDataAnswer(llmJustification)
? llmJustification
: getInclusionJustification(closure);
Fix with Cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants