WorkspaceWithBoard.save_findings posts to blackboard with hardcoded solver_id and double-writes
Severity: Medium
File: src/cain_agent/workspace_ext.py:55-63
save_findings overrides the base class to sync findings into the blackboard, but it hardcodes solver_id="legacy" for every finding regardless of origin, and calls post_finding which appends to self.blackboard._memory.findings:
def save_findings(self, findings: list[object]) -> None:
super().save_findings(findings)
for f in findings:
finding = Finding(**f) if isinstance(f, dict) else f
self.blackboard.post_finding(finding, solver_id="legacy")
Every call to save_findings (which happens in both the test handler and the validation pipeline) re-posts all findings to the blackboard, causing unbounded duplication in self._memory.findings. Additionally, the Finding dataclass from multi_agent/types.py has different fields than the pipeline Finding from findings.py, so Finding(**f) will raise TypeError for any dict that was serialized from the pipeline model (e.g., missing evidence_hash, extra result field).
Why it matters
Running the pipeline through WorkspaceWithBoard causes TypeError crashes on the first save_findings call after findings exist, and even if the schemas matched, the blackboard findings list would grow quadratically with each pipeline re-run.
WorkspaceWithBoard.save_findingsposts to blackboard with hardcoded solver_id and double-writesSeverity: Medium
File:
src/cain_agent/workspace_ext.py:55-63save_findingsoverrides the base class to sync findings into the blackboard, but it hardcodessolver_id="legacy"for every finding regardless of origin, and callspost_findingwhich appends toself.blackboard._memory.findings:Every call to
save_findings(which happens in both the test handler and the validation pipeline) re-posts all findings to the blackboard, causing unbounded duplication inself._memory.findings. Additionally, theFindingdataclass frommulti_agent/types.pyhas different fields than the pipelineFindingfromfindings.py, soFinding(**f)will raiseTypeErrorfor any dict that was serialized from the pipeline model (e.g., missingevidence_hash, extraresultfield).Why it matters
Running the pipeline through
WorkspaceWithBoardcausesTypeErrorcrashes on the firstsave_findingscall after findings exist, and even if the schemas matched, the blackboard findings list would grow quadratically with each pipeline re-run.