Record Class Finding

java.lang.Object
java.lang.Record
ai.tabforge.workshop.model.Finding
Record Components:
severity - CRITICAL pauses the review and escalates to the human; WARNING is included in the report without interruption; INFO is advisory and never blocks the review
agentName - which sub-agent discovered this (e.g. "SecurityAuditorAgent")
filePath - source file path relative to project root
lineNumber - line in the file; -1 if the finding is file-level
message - human-readable description of the problem
suggestion - concrete fix recommendation the developer can act on
confidence - 0.0–1.0 confidence score; below 0.70 is auto-downgraded from WARNING to INFO by OrchestratorAgent#escalate()
ruleId - machine-readable identifier, e.g. "SEC-001", "TXN-003". The identifier of the rule applied by the agent. These are internal values ​​that are defined in the agent class. At the system prompt, we tell Claude which rule IDs he can use: "For SQL injection findings, always use ruleId: SEC-001. For hardcoded secrets, always use ruleId: SEC-002..."

public record Finding(Severity severity, String agentName, String filePath, int lineNumber, String message, String suggestion, double confidence, String ruleId) extends Record
A single issue discovered by a sub-agent during code review.

Analogy: like a compiler diagnostic — a file path, a line number, a severity level, and a human-readable message. A Java compiler produces syntax errors; the Workshop produces architectural, security, and quality findings. Same structure, different domain.

Created by: each SubAgent implementation after parsing the Claude API JSON response. Collected by AgentResultAggregator into the final ReviewReport.

CERTIFICATION NOTE — Domain 1: Agentic Architecture & Orchestration (27%): Finding is the atomic output unit of every sub-agent. Each specialist (SecurityAuditorAgent, TransactionAnalystAgent, etc.) produces a list of these. The AgentResultAggregator collects them from all agents and merges them into the final ReviewReport. This is the data that flows between the agentic loop stages.

CERTIFICATION NOTE — Domain 4: Prompt Engineering & Structured Output (20%): This record IS the output contract for every sub-agent API call. The JSON schema enforced via response_format in each Anthropic API call is derived from the fields of this record. If Claude's response does not match this structure, the retry loop fires. The schema is the contract; this record is its Java representation.

  • Constructor Details

    • Finding

      public Finding(Severity severity, String agentName, String filePath, int lineNumber, String message, String suggestion, double confidence, String ruleId)
      Validates invariants at construction time.

      Confidence must be in [0.0, 1.0]. A value outside this range indicates a bug in the agent's JSON parsing logic.

  • Method Details

    • isBelowConfidenceThreshold

      public boolean isBelowConfidenceThreshold()
      Returns true if this finding is confident enough to trigger escalation.

      CERTIFICATION NOTE — Context Management & Reliability (15% of exam): The 0.70 threshold is the confidence calibration boundary used by OrchestratorAgent#escalate(). Findings below this threshold are downgraded to INFO — the agent signals uncertainty rather than asserting a risk it cannot substantiate.

    • toString

      public final String toString()
      Returns a string representation of this record class. The representation contains the name of the class, followed by the name and value of each of the record components.
      Specified by:
      toString in class Record
      Returns:
      a string representation of this object
    • hashCode

      public final int hashCode()
      Returns a hash code value for this object. The value is derived from the hash code of each of the record components.
      Specified by:
      hashCode in class Record
      Returns:
      a hash code value for this object
    • equals

      public final boolean equals(Object o)
      Indicates whether some other object is "equal to" this one. The objects are equal if the other object is of the same class and if all the record components are equal. Reference components are compared with Objects::equals(Object,Object); primitive components are compared with '=='.
      Specified by:
      equals in class Record
      Parameters:
      o - the object with which to compare
      Returns:
      true if this object is the same as the o argument; false otherwise.
    • severity

      public Severity severity()
      Returns the value of the severity record component.
      Returns:
      the value of the severity record component
    • agentName

      public String agentName()
      Returns the value of the agentName record component.
      Returns:
      the value of the agentName record component
    • filePath

      public String filePath()
      Returns the value of the filePath record component.
      Returns:
      the value of the filePath record component
    • lineNumber

      public int lineNumber()
      Returns the value of the lineNumber record component.
      Returns:
      the value of the lineNumber record component
    • message

      public String message()
      Returns the value of the message record component.
      Returns:
      the value of the message record component
    • suggestion

      public String suggestion()
      Returns the value of the suggestion record component.
      Returns:
      the value of the suggestion record component
    • confidence

      public double confidence()
      Returns the value of the confidence record component.
      Returns:
      the value of the confidence record component
    • ruleId

      public String ruleId()
      Returns the value of the ruleId record component.
      Returns:
      the value of the ruleId record component