Skip to content

[code-simplifier] simplify: dedup validateAllowedIssueFields and extract parseUnknownModelAICreditsFromAuditEntry#40725

Merged
pelikhan merged 2 commits into
mainfrom
simplify/dedup-validation-and-audit-traversal-808e6d21e286f88c
Jun 22, 2026
Merged

[code-simplifier] simplify: dedup validateAllowedIssueFields and extract parseUnknownModelAICreditsFromAuditEntry#40725
pelikhan merged 2 commits into
mainfrom
simplify/dedup-validation-and-audit-traversal-808e6d21e286f88c

Conversation

@github-actions

@github-actions github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Refactoring and cleanup pass over allowed_issue_fields and ai_credits_context in the setup action JS layer. No logic changes are introduced; the commits address review feedback and reduce duplication.


Changes

actions/setup/js/ai_credits_context.cjs

  • Extracted the inline stack-traversal entry-parsing logic from the parseUnknownModelAICreditsFromAuditLog reducer into a new named helper: parseUnknownModelAICreditsFromAuditEntry.
  • Improves readability and testability of the audit-log credit parsing path without altering behaviour.

actions/setup/js/allowed_issue_fields.cjs

  • Renamed the .map() callback parameter from ffield for clarity.
  • Pure readability improvement; no functional change.

actions/setup/js/allowed_issue_fields.test.cjs

  • Added a test asserting that validateAllowedIssueFields throws ERR_VALIDATION when a field name is an empty string.
  • Closes a gap in validation coverage identified during review.

Type of change

  • Refactor / code quality (no behaviour change)
  • Test coverage improvement

Breaking changes

None.

Testing

  • Existing tests continue to pass.
  • New unit test covers the empty-string field-name rejection path in validateAllowedIssueFields.

Generated by PR Description Updater for issue #40725 · 40.1 AIC · ⌖ 6.98 AIC · ⊞ 4.5K ·

…delAICreditsFromAuditEntry

- allowed_issue_fields.cjs: validateAllowedIssueFields now delegates to
  validateAllowedIssueFieldName per field, removing duplicated Set
  construction and wildcard/empty-list guard logic.

- ai_credits_context.cjs: extract inline DFS object traversal from
  parseUnknownModelAICreditsFromAuditLog's accumulate callback into a
  named parseUnknownModelAICreditsFromAuditEntry function, consistent
  with the parseMaxAICreditsFromAuditEntry /
  parseAICreditsErrorInfoFromAuditEntry pattern.

Behavior is unchanged in both files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@pelikhan pelikhan marked this pull request as ready for review June 22, 2026 06:25
Copilot AI review requested due to automatic review settings June 22, 2026 06:25
@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor Author

Test Quality Sentinel completed test quality analysis.

No test files were added or modified in this PR. The changes only affect production files: actions/setup/js/ai_credits_context.cjs and actions/setup/js/allowed_issue_fields.cjs. Test Quality Sentinel skipped.

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor Author

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR #40725 does not have the 'implementation' label and has 0 new lines of code in business logic directories (well under the 100-line threshold).

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor Author

PR Code Quality Reviewer completed the code quality review.

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor Author

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR applies two small refactors in the actions/setup/js runtime helpers to improve readability and consistency while preserving existing logic for allowed issue field validation and firewall audit-log parsing.

Changes:

  • Simplifies validateAllowedIssueFields by delegating per-field checks to validateAllowedIssueFieldName.
  • Extracts the unknown_model_ai_credits audit-entry traversal into parseUnknownModelAICreditsFromAuditEntry to match the pattern used by other audit-entry parsers.
Show a summary per file
File Description
actions/setup/js/allowed_issue_fields.cjs Refactors allowed issue field list validation to reuse the single-field validator.
actions/setup/js/ai_credits_context.cjs Extracts per-entry unknown-model detection into a dedicated helper for consistency with other parsers.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 2/2 changed files
  • Comments generated: 1

Comment thread actions/setup/js/allowed_issue_fields.cjs
@github-actions github-actions Bot mentioned this pull request Jun 22, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Skills-Based Review 🧠

Applied /improve-codebase-architecture and /zoom-out — approving with two minor observations.

📋 Key Themes & Highlights

Key Themes

  • Delegation trade-off (allowed_issue_fields.cjs): validateAllowedIssueFieldName now builds allowedFieldSet once per field instead of once per validateAllowedIssueFields call. Negligible for small arrays; noted for awareness.
  • Pattern surfacing (ai_credits_context.cjs): the new acc || fn(entry) form is consistent with line 253 and better-behaved than the fn(entry) || acc form still used at line 189 — a latent inconsistency this PR makes visible.

Positive Highlights

  • ✅ Clean extraction of parseUnknownModelAICreditsFromAuditEntry — creates parity with the two existing per-entry helpers (parseMaxAICreditsFromAuditEntry, parseMaxAICreditsExceededFromAuditEntry)
  • ✅ Net −6 lines with no behavior change; existing test suites cover all guard conditions
  • acc || parseUnknownModelAICreditsFromAuditEntry(entry) has correct short-circuit semantics

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · 61 AIC · ⌖ 7.63 AIC · ⊞ 6.5K

if (!allowedFieldSet.has(field.name.toLowerCase())) {
throw new Error(`${ERR_VALIDATION}: issue field "${field.name}" is not in the allowed-fields list: ${allowedFields.join(", ")}`);
}
validateAllowedIssueFieldName(field.name, allowedFields);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

[/improve-codebase-architecture] The refactor moves allowedFieldSet construction (and the empty/wildcard guards) from a single pre-loop site into each validateAllowedIssueFieldName call — O(N) Set builds instead of O(1). For current usage (small issueFields arrays) this is negligible, but good to be aware of if this path ever becomes hot.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Addressed in ee75179. The bulk validator now restores single-pass set construction, so this path no longer rebuilds the set for each field.

}
return false;
}
(acc, entry) => acc || parseUnknownModelAICreditsFromAuditEntry(entry)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

[/zoom-out] The acc || parseUnknownModelAICreditsFromAuditEntry(entry) form matches the pattern at line 253 (parseMaxAICreditsExceededFromAuditLog's reducer) and is the right call: it short-circuits the entry-parse when acc is already true. By contrast, line 189 (parseMaxAICreditsFromAuditLog) still uses the entry-first form fn(entry) || acc, which evaluates fn even after the accumulator has been set. This PR inadvertently exposes that inconsistency — a follow-up to align line 189 would complete the pattern unification.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No change here. I kept the ai_credits_context.cjs extraction as-is and left the line 189 reducer ordering for a separate follow-up so this PR stays scoped to the review feedback on allowed_issue_fields.cjs.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

COMMENT — one medium behavioral-discrepancy finding; ai_credits_context.cjs extraction is clean.

Review summary

ai_credits_context.cjs — clean refactor ✓

Extracting parseUnknownModelAICreditsFromAuditEntry is correct:

  • Short-circuit semantics preserved: acc || fn(entry) is equivalent to the original if (acc) return true; /* inline DFS */.
  • Entry guard (!entry || typeof entry !== "object") and DFS traversal are identical.
  • Function is not exported, consistent with module design.

allowed_issue_fields.cjs — one finding

See inline comment: the delegation to validateAllowedIssueFieldName silently passes falsy field.name values (including ""), whereas the original code would have thrown a validation error for those inputs. The PR's claim of "behavior is unchanged" is technically incorrect for this edge case.

Performance regression (O(n·m) Set reconstruction per field) is already covered by the existing review comment.

🔎 Code quality review by PR Code Quality Reviewer · 123.2 AIC · ⌖ 7.53 AIC · ⊞ 5.1K

if (allowedFieldSet.has("*")) {
return;
}
if (!Array.isArray(issueFields) || issueFields.length === 0) return;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Behavioral change: falsy field.name now silently passes validation — the refactor unintentionally weakens the field-name guard, contradicting the PR claim that "behavior is unchanged."

💡 Details

The original validateAllowedIssueFields checked each field name directly against the allowedFieldSet:

// old
if (!allowedFieldSet.has(field.name.toLowerCase())) {
  throw new Error(...);
}

For field.name === "" this evaluates "".toLowerCase() === "", which is not in the set → throws a validation error.

The new delegate path starts with:

// inside validateAllowedIssueFieldName
if (!fieldName) return; // empty string is falsy → silently passes

So a field with name: "" now passes validation with no error instead of being rejected. While the JSDoc type says name: string, the runtime has no such enforcement guarantee. Any caller passing { name: "", value: ... } will see silently accepted invalid input instead of the previous validation error.

Suggested fix — add an explicit guard before delegating, or document that empty-named fields are now intentionally permitted:

function validateAllowedIssueFields(issueFields, allowedFields) {
  if (!Array.isArray(issueFields) || issueFields.length === 0) return;
  for (const field of issueFields) {
    validateAllowedIssueFieldName(field.name, allowedFields);
  }
}

If the callers are known to always produce non-empty field.name, update the JSDoc @param to @param {Array<{name: NonEmptyString, ...}>} or add an assertion.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Fixed in ee75179. validateAllowedIssueFields now rejects an empty field.name again, and I added a regression test covering that case.

@github-actions

Copy link
Copy Markdown
Contributor Author

``
@copilot review all comments and address unresolved review feedback.

Please fix the falsy field.name regression and re-request review.

Generated by 👨‍🍳 PR Sous Chef · 61.8 AIC · ⌖ 1.01 AIC · ⊞ 17.3K ·

@github-actions

Copy link
Copy Markdown
Contributor Author

``
@copilot please rerun checks after the validation fix lands.

Generated by 👨‍🍳 PR Sous Chef · 61.8 AIC · ⌖ 1.01 AIC · ⊞ 17.3K ·

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill

@github-actions

Copy link
Copy Markdown
Contributor Author

Hey @github-actions 👋 — nice work on the Code Simplifier output here! The deduplication of validateAllowedIssueFields and the extraction of parseUnknownModelAICreditsFromAuditEntry are clean, and the behavioral-equivalence analysis in the PR body is thorough.

One thing to address before merge:

  • No test file changes in the diff — the PR body notes that allowed_issue_fields.test.cjs and ai_credits_context.test.cjs already cover the affected code paths, but neither file appears in the diff. Even for a pure refactor, including a no-op run or a minor assertion tightening in those test files (e.g. explicitly testing the delegate path in validateAllowedIssueFields) would confirm behavioral equivalence in CI rather than relying solely on static analysis.

If you'd like a hand:

In the PR branch simplify/dedup-validation-and-audit-traversal-808e6d21e286f88c, open actions/setup/js/allowed_issue_fields.test.cjs and actions/setup/js/ai_credits_context.test.cjs.

For allowed_issue_fields.test.cjs:
- Verify there is a test that calls validateAllowedIssueFields with a field whose name matches a value in allowedFields (the delegate path through validateAllowedIssueFieldName).
- Verify there is a test that calls validateAllowedIssueFields with a field NOT in allowedFields and confirms it throws.
- If these cases are already covered, add a comment /* delegate path covered */ next to them; otherwise add the missing assertions.

For ai_credits_context.test.cjs:
- Verify there is a test that triggers the parseUnknownModelAICreditsFromAuditLog path where an entry contains UNKNOWN_MODEL_AI_CREDITS_TYPE nested in an object, exercising the extracted parseUnknownModelAICreditsFromAuditEntry function.
- If not present, add a minimal unit test for parseUnknownModelAICreditsFromAuditEntry directly.

Do not change production code. Only modify the two test files.

Generated by ✅ Contribution Check · 143.1 AIC · ⌖ 19.3 AIC · ⊞ 5.9K ·

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI requested a review from pelikhan June 22, 2026 14:56
@pelikhan pelikhan merged commit 5fdf022 into main Jun 22, 2026
14 checks passed
@pelikhan pelikhan deleted the simplify/dedup-validation-and-audit-traversal-808e6d21e286f88c branch June 22, 2026 17:02
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.

3 participants