Skip to content

Add maxissues threshold support for CI/CD rule enforcement - #15

Merged
pjaincertinia2025 merged 11 commits into
certinia:mainfrom
B1naryVision:add-support-for-issue-cap
Mar 5, 2026
Merged

pjaincertinia2025 merged 11 commits into
certinia:mainfrom
B1naryVision:add-support-for-issue-cap

Conversation

@B1naryVision

@B1naryVision B1naryVision commented Feb 19, 2026 •

Copy link
Copy Markdown
Contributor

Currently, asist fails if any issues are detected (equivalent to a hard cap of 0). This change allows users to define a custom limit per rule.

💡 Why is this needed?
On large or legacy repositories, "perfect" compliance is often impossible to achieve overnight. By allowing a maxIssues threshold, teams can:

Grandfather in existing issues: Set the cap to the current issue count to prevent new regressions.

Incremental Improvement: Gradually lower the cap over time as technical debt is cleared.

CI Adoption: Enable the analyzer in CI/CD pipelines without immediately breaking the build for existing debt.

🛠 Proposed Changes
Added a maxIssues configuration option per rule.

Default Behavior: If no cap is defined, it defaults to 0, maintaining the current strict enforcement behavior.

Logic: The build fails only if actualIssues > maxIssues.

Why only CI/CD?: It only exits with error codes if it's in CI/CD mode, otherwise it simply prints out the issues.
Perhaps we would also like to Print a warning outside of CI/CD? Would that mess with baseline or anything though?

🧪 WIP Notes (Seeking Early Input)
I am raising this as a Draft PR to get feedback on the implementation logic before I finalize the test suite. Specifically:

Does the flag naming (maxIssues) align with the project's naming conventions?
Here's some other options I considered.

  • issuethreshold
  • maxallowedissues
  • cicdmaxissues
  • failon

Are there any edge cases in the threshold logic I should account for before I write the unit tests?

I added a printing log in CI/CD mode, is this a breaking change as it now no longer ONLY prints the issues?

Harold Albertsson added 2 commits February 19, 2026 12:07
- Add MaxIssues field to RuleMetadataOverride (Rule.go)
- Add GetRuleMaxIssues method to Config to read the configured threshold (config.go)
- Add checkThresholdViolations in output.go to compare findings against thresholds
  and exit non-zero when a rule exceeds its configured maxissues in CI/CD mode
- Add maxissues property description and usage to README and index.md
- Update .asist.example.yaml with maxissues example and explanatory comments
Comment thread output/output.go
for ruleId, count := range findingsPerRule {
maxIssuesAllowed := configFile.GetRuleMaxIssues(ruleId)

if count > maxIssuesAllowed {

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.

This may be considered a breaking change if we really want CI/CD to only print the issues.

This just prints when you go over, default behaviour is 0 allowed in CI/CD

Could be prettified too, it shows just after printing issues, so probably need to add a linebreak before if we do decide to keep it.

Eg. example

  {
   "ID": "XSSMergeField",
   "Name": "Potential XSS with mergefield",
   "Description": "Using a merge field inside a script or style tag may introduce an XSS issue. Consider adding an encode method for the merge field; otherwise, ensure that all user inputs are sanitized properly.",
   "Severity": "High",
   "RuleCategory": "Security",
   "Occurrence": {
    "File": "<redacted>",
    "Line": "            <redacted>",
    "LineNumber": 13,
    "ColumnRange": [
     52,
     83
    ]
   }
  }
 ]
}
Threshold violation: Rule XSSMergeField has 50 issues (max allowed: 5)

@B1naryVision B1naryVision Feb 27, 2026 •

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.

Prettified it a little bit more, I added a space

... JSON
}

Threshold violations:
  Rule XSSDomHtml has 40 issues (max allowed: 0)
  Rule XSSMergeField has 36 issues (max allowed: 5)

2 rule(s) exceed their maxissues threshold.

Comment thread docs/index.md
2. Enable the `Custom Binary Enabled` setting
3. Provide the path to your ASIST binary in `Custom Binary Path`
1. Enable the `Custom Binary Enabled` setting
1. Provide the path to your ASIST binary in `Custom Binary Path`

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.

Context: 1. 1. 1 etc is valid for MD, it auto-increments.

Comment thread docs/index.md


### 🫣 .gitignore and .forceignore files
## 🫣 .gitignore and .forceignore files

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.

I did some nitpicking, a H1 -> H3.

Arguably this should have stayed a H3 and CI/CD should be a H2 but...
Happy to change it up 😅

Comment thread docs/index.md

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.

Future enhancement I might do, is make the index/readme copy from a central file with these details so I don't need to copy-paste across except for the headers/footers. Maybe it does and I just didn't see it?

gkumarcertinia
gkumarcertinia previously approved these changes Feb 23, 2026
Comment thread README.md Outdated
* Exclude files or directories for specific rules
* Add custom regex rules
* Define rules to be run in CI/CD mode
- Enable/disable all the standard rules

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
- Enable/disable all the standard rules
- Enable/disable all the standard rules

Comment thread docs/index.md Outdated
cicdrules:
- "XSSLabel"
- "XSSMergeField"
- "XSSDomHtml"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Should this list be alphabetical?

Comment thread output/output.go Outdated

/**
* Checks if any rule exceeds its configured maxissues.
* Default maxissues is 0 (no issues allowed) if not explicitly set.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Default and 'not explicitly set' mean the same. So there is redundancy in this sentence.

@jwoodwardcertinia jwoodwardcertinia left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM

Harold Albertsson added 3 commits February 27, 2026 10:10
- Alphabetising cicd rules
- Removing rogue spaces at the end of list
- Ordering the rules to ensure they are deterministic for testing
- Removed unintentional repetition in comment
- Added padding between the violations
- Added a message for saying how many violated rules there are
Added:
- Integration tests
- Output tests
- config tests
@B1naryVision
B1naryVision marked this pull request as ready for review February 27, 2026 11:21

@ajaincertinia ajaincertinia left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Hi @B1naryVision, we had internal discussion regarding the --list-rule case, and decided that maxissues should be renamed to cicdmaxissues (as per your earlier suggestion), and --list-rule should print this property.

- Rename RuleMetadataOverride.MaxIssues → CicdMaxIssues; update YAML/JSON
  deserialization key from `maxissues` to `cicdmaxissues` accordingly
- Add CicdMaxIssues int field to RuleMetadata so --list-rules output
  includes the configured threshold per rule (default 0)
- Populate CicdMaxIssues on RuleMetadata via Override() at rule load time
- Update all tests, fixtures, docs, example config, and changelog
Comment thread output/output_test.go Outdated
}
}

func TestCheckThresholdViolations_WhenMaxIssuesNotSet_DefaultsToZero(t *testing.T) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
func TestCheckThresholdViolations_WhenMaxIssuesNotSet_DefaultsToZero(t *testing.T) {
func TestCheckThresholdViolations_WhenCicdMaxIssuesNotSet_DefaultsToZero(t *testing.T) {

Comment thread output/output_test.go Outdated

//Then
if !result {
t.Errorf("Expected violation when maxissues defaults to 0 and rule has 1 finding")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
t.Errorf("Expected violation when maxissues defaults to 0 and rule has 1 finding")
t.Errorf("Expected violation when cicdmaxissues defaults to 0 and rule has 1 finding")

Comment thread config/config.go Outdated
* Returns the max allowed issues for a specific rule ID.
* Returns ruleoverrides.<rule>.cicdmaxissues if set, otherwise 0.
*/
func (c *Config) GetRuleMaxIssues(ruleId rules.RuleID) int {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Not sure but should GetRuleMaxIssues also be renamed to GetRuleCicdMaxIssues?

@B1naryVision B1naryVision Mar 3, 2026 •

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.

I don't mind it, I think the method is clear. But happy to change it if you feel like it should be renamed

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It's okay to me.

ajaincertinia
ajaincertinia previously approved these changes Mar 3, 2026
Comment thread README.md Resolved
Co-authored-by: Govardhan <13658588+gkumarcertinia@users.noreply.github.com>
gkumarcertinia
gkumarcertinia previously approved these changes Mar 3, 2026
- Add CicdMaxIssues *int field to CustomRegexRule config struct
- Propagate it through NewCustomRule into RuleMetadata.CicdMaxIssues
- Extend GetRuleCicdMaxIssues to fall back to CustomRegexRules after
  checking RuleOverrides, so custom rule thresholds are respected in
  CI/CD mode (-j)
- Update config testdata fixtures (YAML + JSON) with cicdmaxissues
- Update CustomRule_test.go and config_test.go with new tests
- Update README, docs/index.md, .asist.example.yaml, and changelog
@B1naryVision B1naryVision reopened this Mar 5, 2026
@B1naryVision

Copy link
Copy Markdown
Contributor Author

I meant to merge, accidentally closed. I just realised I don't see a merge button

@pjaincertinia2025
pjaincertinia2025 merged commit 4549282 into certinia:main Mar 5, 2026
16 checks passed
@B1naryVision
B1naryVision deleted the add-support-for-issue-cap branch March 5, 2026 14:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants