Skip to content

feat(governance): add competition events subsumption bundle#23640

Open
BrianCLong wants to merge 1 commit intomainfrom
feature/summit-subsumption-v2-competition-events-16575147726239482173
Open

feat(governance): add competition events subsumption bundle#23640
BrianCLong wants to merge 1 commit intomainfrom
feature/summit-subsumption-v2-competition-events-16575147726239482173

Conversation

@BrianCLong
Copy link
Copy Markdown
Owner

@BrianCLong BrianCLong commented Apr 9, 2026

This PR introduces the necessary architectural foundations for tracking and handling regulatory competition events within the Summit OSINT platform. It follows the specifications for the 'Summit Subsumption Plan v2', specifically targeting anti-competitive conduct allegations.

The changes encompass:

  1. Subsumption Ground Truth: Adding manifest.yaml and claims.md defining the claim registry mapping.
  2. GraphRAG Schema: A new CompetitionEvent schema extending EvidenceReport to track REGULATORY_COMPETITION_EVENT typologies.
  3. Data Ingestion Connector: A deterministic REST connector stub for parsing articles (regulatoryNews.ts) and corresponding unit tests.
  4. Policy Engine Rules: A base antitrust policy classification configuration (antitrust.yml).
  5. Agent Implementation: A skeleton implementation of CompetitionRiskAgent.
  6. Documentation: Initial stubs for standards, operational runbooks, and data handling security guidelines.
  7. CI/Benchmarking Stubs: Placeholder scripts for performance benchmarking and post-merge monitoring.

PR created automatically by Jules for task 16575147726239482173 started by @BrianCLong

Summary by CodeRabbit

  • New Features

    • Added competition risk analysis capability to detect potential anticompetitive conduct.
    • Added automatic extraction of competition events from regulatory news sources.
  • Documentation

    • Added security and data handling requirements for competition event data.
    • Added operational runbook and standards documentation for competition events.
    • Added claim registry and manifest for competition event tracking.
  • Tests

    • Added tests for competition event extraction functionality.
  • Chores

    • Added GitHub policy configuration for antitrust classification flagging.
    • Added benchmark and monitoring infrastructure for competition analysis.

Creates the initial architectural implementation for the competition events subsumption plan.
- Added `subsumption/competition-events/manifest.yaml` and `claims.md` for ground truth capture.
- Defined GraphRAG schema `CompetitionEvent` in `src/graphrag/schema/competitionEvent.ts`.
- Created rest connector `extractCompetitionEvent` in `src/connectors/rest/regulatoryNews.ts` with tests.
- Added antitrust GitHub Actions policy in `.github/policies/competition/antitrust.yml`.
- Created agent stub `CompetitionRiskAgent`.
- Added stubs for benchmark and monitoring scripts.
- Added standards, security, and runbook documentation to `docs/`.

Co-authored-by: BrianCLong <6404035+BrianCLong@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the 'Competition Events' feature, which includes a risk agent, a regulatory news extractor, and comprehensive documentation for operations, security, and standards. The feedback primarily addresses the 'manifest.yaml' file, which currently contains several placeholder values and incorrect file paths inherited from a template. Additionally, there are suggestions to improve the robustness of the antitrust policy matching condition and to properly handle an unused parameter in the risk agent.

Comment on lines +3 to +8
title: "TEMPLATE: Replace with ITEM title"
links: []
type: "unknown"
date_version: "unknown"
intriguing_claim: "TEMPLATE: 1–2 sentences"
item_slug: "_template"
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.

high

The manifest metadata contains placeholder values from the template. These should be updated to reflect the specific 'Competition Events' bundle.

  title: "Competition Events Subsumption Bundle"
  links: []
  type: "governance"
  date_version: "1.0.0"
  intriguing_claim: "Tracks regulatory competition events and anti-competitive conduct allegations."
item_slug: "competition-events"


claim_registry:
mode: "missing-item"
claims_file: "subsumption/_template/claims.md"
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.

high

The claims_file path points to the template directory. It should point to the claims.md file created in this PR.

  claims_file: "subsumption/competition-events/claims.md"

Comment on lines +35 to +37
- "docs/standards/subsumption-bundle-framework.md"
- "docs/security/data-handling/subsumption-bundle-framework.md"
- "docs/ops/runbooks/subsumption-bundle-framework.md"
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.

high

The docs_targets paths point to generic framework documentation. They should be updated to match the documentation files added in this PR.

  - "docs/standards/competition-events.md"
  - "docs/security/data-handling/competition-events.md"
  - "docs/ops/runbooks/competition-events.md"

@@ -0,0 +1,5 @@
export class CompetitionRiskAgent {
analyze(text: string) {
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.

medium

The text parameter is currently unused. Prefixing it with an underscore is a common convention to indicate an intentionally unused parameter in TypeScript.

Suggested change
analyze(text: string) {
analyze(_text: string) {

rules:
- id: antitrust-01
description: Flag mentions of anticompetitive conduct
condition: text contains "anti-competitive"
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.

medium

The condition text contains "anti-competitive" is case-sensitive and very specific. It will miss variations like "anticompetitive" or "Anti-competitive". Consider using a more flexible matching strategy if supported by the policy engine.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 9, 2026

Walkthrough

Adds a new competition events feature including antitrust policy configuration, regulatory news extraction connector, risk analysis agent, schema definitions, operational documentation, manifest files, and related tests.

Changes

Cohort / File(s) Summary
Policy Configuration
.github/policies/competition/antitrust.yml
New GitHub policy defining antitrust classification rule to flag anticompetitive conduct when "anti-competitive" text is detected.
Documentation
docs/ops/runbooks/competition-events.md, docs/security/data-handling/competition-events.md, docs/standards/competition-events.md
Three new documentation pages covering operational runbook (alerting on extraction failures >5% and schema mismatches), security data-handling requirements (public news only, no logging of raw prompts/embeddings, 30-day raw data retention), and supported event formats (JSON and Graph/Neo4j).
Stub Scripts
scripts/bench/competition-event.ts, scripts/monitoring/competition-drift.ts
Placeholder benchmark and monitoring scripts with console output stubs for future implementation.
Core Implementation
src/agents/competition-risk-agent.ts, src/connectors/rest/regulatoryNews.ts, src/graphrag/schema/competitionEvent.ts
New CompetitionRiskAgent class with analyze() method returning fixed risk score and antitrust flags; extractCompetitionEvent() function computing SHA-256 hash of articles and returning structured events; CompetitionEvent interface extending EvidenceReport with event type, actors, and claims fields.
Subsumption Manifest
subsumption/competition-events/manifest.yaml, subsumption/competition-events/claims.md
Versioned manifest template with gating rules, evidence schemas, documentation targets, and dependency tracking; claim registry mapping five planned components (risk detector, event ingestion, actor conflict edges, classification, policy tagging) to claim identifiers.
Tests
tests/connectors/regulatoryNews.test.ts
New test verifying extractCompetitionEvent() returns correct event type and non-empty ID for sample regulatory articles.

Sequence Diagram

sequenceDiagram
    participant Client
    participant REST Connector
    participant Competition Agent
    participant Response
    
    Client->>REST Connector: POST article text
    REST Connector->>REST Connector: Compute SHA-256 hash
    REST Connector->>Competition Agent: Pass extracted CompetitionEvent
    Competition Agent->>Competition Agent: Analyze text for risk
    Competition Agent->>Response: Return {riskScore: 0.8, flags: [antitrust]}
    Response->>Client: Return analysis result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A competition tale we weave,
With agents sharp and risk relief,
Where antitrust flags brightly soar,
And regulatory news forevermore!
News extracted, analyzed with care,
Competition events everywhere! 📋

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is substantially incomplete against the template, missing critical sections: Risk & Surface (required), Assumption Ledger, Execution Governor & Customer Impact, Evidence Bundle, Investigation Trust Doctrine Checklist, Security Impact, and Green CI Contract Checklist. Complete all required sections in the template, particularly Risk & Surface, Evidence Bundle checklist items, and Green CI Contract Checklist before merge.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main change: adding a competition events subsumption bundle with governance foundations.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/summit-subsumption-v2-competition-events-16575147726239482173

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7f8719f8ce

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

type: "unknown"
date_version: "unknown"
intriguing_claim: "TEMPLATE: 1–2 sentences"
item_slug: "_template"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Set bundle slug to competition-events

item_slug is still _template, so any tooling that derives identity from the manifest will attribute this bundle’s evidence to the template namespace instead of competition-events (the repo’s verifier extracts slug text and writes it into emitted evidence metadata). That creates collisions with other template-derived bundles and makes this new bundle non-addressable as its own ITEM.

Useful? React with 👍 / 👎.

const hash = crypto.createHash('sha256').update(article).digest('hex');
return {
id: hash,
type: "REGULATORY_COMPETITION_EVENT",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Emit schema discriminator as event_type

The extractor returns type, but the newly added CompetitionEvent schema defines event_type as the discriminator. This mismatch means payloads from extractCompetitionEvent do not conform to the declared schema and can be dropped or misclassified by consumers expecting CompetitionEvent-shaped objects.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🧹 Nitpick comments (3)
scripts/monitoring/competition-drift.ts (1)

1-1: Stub file needs implementation or tracking.

This monitoring script is a placeholder with no functional drift detection logic. The PR description mentions "post-merge monitoring" stubs.

Would you like me to:

  1. Generate a functional monitoring implementation for competition event drift detection (schema changes, data quality metrics, alert thresholds, etc.), or
  2. Open an issue to track this as deferred work with acceptance criteria?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/monitoring/competition-drift.ts` at line 1, The file currently only
contains a stub console.log; replace it with a proper monitoring implementation
by adding a top-level async function monitorCompetitionDrift that orchestrates
drift checks, and implement helper functions detectSchemaChanges,
computeDataQualityMetrics, and sendAlert; detectSchemaChanges should compare
current event schema to a stored baseline (e.g., loadBaselineSchema/loadBaseline
function), computeDataQualityMetrics should calculate completeness, null rates
and value distributions for key fields, and monitorCompetitionDrift should
evaluate thresholds and call sendAlert (or log) when drift or quality thresholds
are exceeded; ensure the script exports or runs monitorCompetitionDrift and
include configuration for thresholds and a persistent baseline store or an issue
if baseline is missing.
scripts/bench/competition-event.ts (1)

1-1: Stub file needs implementation or tracking.

This benchmark script is a placeholder with no functional implementation. The PR description acknowledges these as "placeholder scripts for performance benchmarking."

Would you like me to:

  1. Generate a functional benchmark implementation for competition event processing (measuring ingestion throughput, query performance, etc.), or
  2. Open an issue to track this as deferred work with acceptance criteria?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/bench/competition-event.ts` at line 1, Replace the placeholder
console.log in scripts/bench/competition-event.ts with a tracked TODO and open
an issue to defer the benchmark work: create an issue describing required
acceptance criteria (measure ingestion throughput, query latency, realistic
dataset generation, repeatable runs, and CI gating), reference this file
(scripts/bench/competition-event.ts) and its current stub
(console.log('Benchmark script stub')), and add a short TODO comment in the file
pointing to the issue number so future contributors know this is intentionally
deferred.
tests/connectors/regulatoryNews.test.ts (1)

5-10: Strengthen this test to assert deterministic contract, not just truthiness.

assert.ok(event.id) won’t catch hash regressions or shape regressions.

Suggested test hardening
 import test from 'node:test';
 import assert from 'node:assert';
+import crypto from 'node:crypto';
 import { extractCompetitionEvent } from '../../src/connectors/rest/regulatoryNews.js';
 
 test('extractCompetitionEvent', () => {
   const article = 'OpenAI formally requested regulatory scrutiny from California AG.';
   const event = extractCompetitionEvent(article);
+  const expectedId = crypto.createHash('sha256').update(article).digest('hex');
   assert.strictEqual(event.type, 'REGULATORY_COMPETITION_EVENT');
-  assert.ok(event.id);
+  assert.strictEqual(event.id, expectedId);
+  assert.deepStrictEqual(event.actors, []);
+  assert.deepStrictEqual(event.claims, []);
 });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/connectors/regulatoryNews.test.ts` around lines 5 - 10, The test uses
assert.ok(event.id) which only checks truthiness; change it to assert a
deterministic contract: call extractCompetitionEvent(article) and
assert.strictEqual(event.type, 'REGULATORY_COMPETITION_EVENT') and then either
assert.strictEqual(event.id, '<expected-deterministic-id>') (replace with the
known hash/code produced for that article) or assert.match(event.id,
/^[a-f0-9]{...}$/) to lock down the id format, and additionally assert deep
properties of the event (e.g., assert.strictEqual(event.text, article) or
assert.deepStrictEqual(event, { type: ..., id: ..., text: ... })) so the test
fails on hash/shape regressions; update the test in
tests/connectors/regulatoryNews.test.ts around the extractCompetitionEvent call
accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/policies/competition/antitrust.yml:
- Line 5: The condition currently only checks for the exact string
"anti-competitive"; replace it with a case-insensitive regex that matches both
hyphenated and non-hyphenated forms, e.g. change the rule from condition: text
contains "anti-competitive" to a regex match like condition: text matches
"(?i)\\banti-?competitive\\b" so it catches "anti-competitive",
"anticompetitive", and case variants.

In `@docs/ops/runbooks/competition-events.md`:
- Around line 4-6: The runbook's alert threshold "extraction fails >5%"
conflicts with the declared SLO "SLO: 99% parse success" (1% failure budget);
update the alerting threshold to align with the SLO (e.g., trigger when
extraction fails >1% or a lower value like >0.5% for early warning) or change
the SLO to match the existing alerting (e.g., SLO: 95% parse success) and make
the change in the lines containing "extraction fails >5%" and "SLO: 99% parse
success" so the two values are consistent.

In `@docs/security/data-handling/competition-events.md`:
- Line 7: The phrase "Retention: 30 days raw, permanent structured" lacks a
compliance guardrail—update the doc to replace or augment "permanent structured"
with an explicit retention and reevaluation policy: define a structured-record
retention_duration (e.g., X years or indefinite with conditions), a periodic
review_cycle (e.g., annually), responsible_role or team (e.g., Data Protection
Officer / Data Retention Owner), required transformations
(pseudonymization/aggregation) and legal_basis for indefinite storage, and
mention audit/logging and deletion procedures (how to delete or re-evaluate
records and who approves exceptions) so the structured retention has clear
operational and compliance controls.

In `@src/agents/competition-risk-agent.ts`:
- Around line 2-3: The analyze method currently returns a hardcoded antitrust
risk for every input; change analyze(text: string) in the CompetitionRiskAgent
to compute a real heuristic: scan the input for configurable antitrust
keywords/phrases (e.g., "collude", "price fixing", "bid rigging", "market
allocation"), count hits and compute a normalized riskScore (0.0–1.0) based on
hits and text length, and populate flags only when relevant (e.g., include
'antitrust' or more specific flags like 'price-fixing'); if no keywords are
found return riskScore near 0 and an empty flags array. Ensure the function
signature remains analyze(text: string) and add a simple unit test or comment
describing the keyword list so maintainers can tune thresholds.

In `@src/connectors/rest/regulatoryNews.ts`:
- Around line 3-4: The function extractCompetitionEvent creates a hash from the
article without validating input; add an early guard in extractCompetitionEvent
that checks if article is null/undefined or article.trim() === '' and reject it
(e.g., return null or throw a ValidationError) before calling crypto.createHash,
so blank or whitespace-only inputs are not hashed or turned into events.
- Around line 5-8: The returned object in the regulatory news connector is using
the wrong field name "type" which must be renamed to "event_type" to match the
schema; update the return value (the object that includes id: hash, type:
"REGULATORY_COMPETITION_EVENT", actors: []) to replace the "type" property with
"event_type" (event_type: "REGULATORY_COMPETITION_EVENT") so that the output of
the regulatoryNews connector conforms to the competition event schema and passes
validation.

In `@src/graphrag/schema/competitionEvent.ts`:
- Line 4: The schema uses event_type but the regulatory extractor/test contract
expects the discriminant key type, causing a shape mismatch; update the
CompetitionEvent schema to use type: 'REGULATORY_COMPETITION_EVENT' (replace
event_type) and search/rename any references to event_type in related
code/tests/extractors to use type so the discriminant key is consistent with the
regulatory extractor and downstream consumers.

In `@subsumption/competition-events/manifest.yaml`:
- Line 3: The manifest still contains template placeholders (e.g., title:
"TEMPLATE: Replace with ITEM title") and references to the `_template` and
`subsumption-bundle-framework` artifacts which prevent the competition-events
bundle from resolving correct claims/docs/fixtures; update the manifest.yaml to
replace the TEMPLATE placeholders with the real `competition-events` values and
swap any `_template` and `subsumption-bundle-framework` artifact references to
the actual competition-events artifact names used by this bundle (check fields
around title, any `artifact:` entries, `docs`, `fixtures`, and `claims` keys) so
all references point to the competition-events resources instead of the
template/framework ones.
- Around line 22-23: The manifest currently sets required_checks_status:
"assumed" while deny_by_default_required: true which weakens enforcement; change
required_checks_status to a non-assumed value (e.g., "required" or "enforced")
so the deny-by-default gate requires actual CI verification, and apply the same
change for the other occurrence mentioned (lines 56-57) to ensure both places
use the stricter status.

---

Nitpick comments:
In `@scripts/bench/competition-event.ts`:
- Line 1: Replace the placeholder console.log in
scripts/bench/competition-event.ts with a tracked TODO and open an issue to
defer the benchmark work: create an issue describing required acceptance
criteria (measure ingestion throughput, query latency, realistic dataset
generation, repeatable runs, and CI gating), reference this file
(scripts/bench/competition-event.ts) and its current stub
(console.log('Benchmark script stub')), and add a short TODO comment in the file
pointing to the issue number so future contributors know this is intentionally
deferred.

In `@scripts/monitoring/competition-drift.ts`:
- Line 1: The file currently only contains a stub console.log; replace it with a
proper monitoring implementation by adding a top-level async function
monitorCompetitionDrift that orchestrates drift checks, and implement helper
functions detectSchemaChanges, computeDataQualityMetrics, and sendAlert;
detectSchemaChanges should compare current event schema to a stored baseline
(e.g., loadBaselineSchema/loadBaseline function), computeDataQualityMetrics
should calculate completeness, null rates and value distributions for key
fields, and monitorCompetitionDrift should evaluate thresholds and call
sendAlert (or log) when drift or quality thresholds are exceeded; ensure the
script exports or runs monitorCompetitionDrift and include configuration for
thresholds and a persistent baseline store or an issue if baseline is missing.

In `@tests/connectors/regulatoryNews.test.ts`:
- Around line 5-10: The test uses assert.ok(event.id) which only checks
truthiness; change it to assert a deterministic contract: call
extractCompetitionEvent(article) and assert.strictEqual(event.type,
'REGULATORY_COMPETITION_EVENT') and then either assert.strictEqual(event.id,
'<expected-deterministic-id>') (replace with the known hash/code produced for
that article) or assert.match(event.id, /^[a-f0-9]{...}$/) to lock down the id
format, and additionally assert deep properties of the event (e.g.,
assert.strictEqual(event.text, article) or assert.deepStrictEqual(event, { type:
..., id: ..., text: ... })) so the test fails on hash/shape regressions; update
the test in tests/connectors/regulatoryNews.test.ts around the
extractCompetitionEvent call accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 19146f72-9f8c-4a4f-bdb9-c8661d98851f

📥 Commits

Reviewing files that changed from the base of the PR and between 56b074b and 7f8719f.

📒 Files selected for processing (12)
  • .github/policies/competition/antitrust.yml
  • docs/ops/runbooks/competition-events.md
  • docs/security/data-handling/competition-events.md
  • docs/standards/competition-events.md
  • scripts/bench/competition-event.ts
  • scripts/monitoring/competition-drift.ts
  • src/agents/competition-risk-agent.ts
  • src/connectors/rest/regulatoryNews.ts
  • src/graphrag/schema/competitionEvent.ts
  • subsumption/competition-events/claims.md
  • subsumption/competition-events/manifest.yaml
  • tests/connectors/regulatoryNews.test.ts

rules:
- id: antitrust-01
description: Flag mentions of anticompetitive conduct
condition: text contains "anti-competitive"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Broaden the match condition to avoid false negatives.

The current condition only catches the exact hyphenated phrase and will miss common variants like anticompetitive (and likely case variants), so antitrust mentions can slip through.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/policies/competition/antitrust.yml at line 5, The condition
currently only checks for the exact string "anti-competitive"; replace it with a
case-insensitive regex that matches both hyphenated and non-hyphenated forms,
e.g. change the rule from condition: text contains "anti-competitive" to a regex
match like condition: text matches "(?i)\\banti-?competitive\\b" so it catches
"anti-competitive", "anticompetitive", and case variants.

Comment on lines +4 to +6
* extraction fails >5%
* schema mismatch
* SLO: 99% parse success
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Alert threshold conflicts with stated SLO.

A 99% parse-success SLO means a 1% failure budget, but the runbook alerts only after failures exceed 5%, which is too late for SLO protection.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/ops/runbooks/competition-events.md` around lines 4 - 6, The runbook's
alert threshold "extraction fails >5%" conflicts with the declared SLO "SLO: 99%
parse success" (1% failure budget); update the alerting threshold to align with
the SLO (e.g., trigger when extraction fails >1% or a lower value like >0.5% for
early warning) or change the SLO to match the existing alerting (e.g., SLO: 95%
parse success) and make the change in the lines containing "extraction fails
>5%" and "SLO: 99% parse success" so the two values are consistent.

* Never log:
* raw prompts
* internal embeddings
* Retention: 30 days raw, permanent structured
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

“Permanent structured” retention needs a compliance guardrail.

Without an explicit deletion/reevaluation policy for structured records, this creates a data-minimization and retention-risk gap.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/security/data-handling/competition-events.md` at line 7, The phrase
"Retention: 30 days raw, permanent structured" lacks a compliance
guardrail—update the doc to replace or augment "permanent structured" with an
explicit retention and reevaluation policy: define a structured-record
retention_duration (e.g., X years or indefinite with conditions), a periodic
review_cycle (e.g., annually), responsible_role or team (e.g., Data Protection
Officer / Data Retention Owner), required transformations
(pseudonymization/aggregation) and legal_basis for indefinite storage, and
mention audit/logging and deletion procedures (how to delete or re-evaluate
records and who approves exceptions) so the structured retention has clear
operational and compliance controls.

Comment on lines +2 to +3
analyze(text: string) {
return { riskScore: 0.8, flags: ['antitrust'] };
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

analyze currently classifies every text as antitrust risk.

This is functionally incorrect for a production path and will flood downstream systems with false positives.

Proposed minimal baseline behavior
 export class CompetitionRiskAgent {
   analyze(text: string) {
-    return { riskScore: 0.8, flags: ['antitrust'] };
+    const normalized = text.toLowerCase();
+    const antitrustHit = /(anti-competitive|anticompetitive|antitrust|monopoly)/.test(normalized);
+    return {
+      riskScore: antitrustHit ? 0.8 : 0.1,
+      flags: antitrustHit ? ['antitrust'] : [],
+    };
   }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
analyze(text: string) {
return { riskScore: 0.8, flags: ['antitrust'] };
analyze(text: string) {
const normalized = text.toLowerCase();
const antitrustHit = /(anti-competitive|anticompetitive|antitrust|monopoly)/.test(normalized);
return {
riskScore: antitrustHit ? 0.8 : 0.1,
flags: antitrustHit ? ['antitrust'] : [],
};
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/agents/competition-risk-agent.ts` around lines 2 - 3, The analyze method
currently returns a hardcoded antitrust risk for every input; change
analyze(text: string) in the CompetitionRiskAgent to compute a real heuristic:
scan the input for configurable antitrust keywords/phrases (e.g., "collude",
"price fixing", "bid rigging", "market allocation"), count hits and compute a
normalized riskScore (0.0–1.0) based on hits and text length, and populate flags
only when relevant (e.g., include 'antitrust' or more specific flags like
'price-fixing'); if no keywords are found return riskScore near 0 and an empty
flags array. Ensure the function signature remains analyze(text: string) and add
a simple unit test or comment describing the keyword list so maintainers can
tune thresholds.

Comment on lines +3 to +4
export function extractCompetitionEvent(article: string) {
const hash = crypto.createHash('sha256').update(article).digest('hex');
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Reject empty/blank articles before hashing.

Creating events from blank input makes ingestion noisy and can produce duplicate placeholder events.

Suggested input validation
 export function extractCompetitionEvent(article: string) {
+  if (!article || article.trim().length === 0) {
+    throw new Error('article must be a non-empty string');
+  }
   const hash = crypto.createHash('sha256').update(article).digest('hex');
   return {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export function extractCompetitionEvent(article: string) {
const hash = crypto.createHash('sha256').update(article).digest('hex');
export function extractCompetitionEvent(article: string) {
if (!article || article.trim().length === 0) {
throw new Error('article must be a non-empty string');
}
const hash = crypto.createHash('sha256').update(article).digest('hex');
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/connectors/rest/regulatoryNews.ts` around lines 3 - 4, The function
extractCompetitionEvent creates a hash from the article without validating
input; add an early guard in extractCompetitionEvent that checks if article is
null/undefined or article.trim() === '' and reject it (e.g., return null or
throw a ValidationError) before calling crypto.createHash, so blank or
whitespace-only inputs are not hashed or turned into events.

Comment on lines +5 to +8
return {
id: hash,
type: "REGULATORY_COMPETITION_EVENT",
actors: [],
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Locate schema and inspect event field names =="
fd -i 'competitionEvent.ts' | while read -r f; do
  echo "--- $f ---"
  rg -n -C2 'interface\s+CompetitionEvent|event_type|type\s*:' "$f"
done

echo
echo "== Inspect connector payload fields =="
fd -i 'regulatoryNews.ts' | while read -r f; do
  echo "--- $f ---"
  rg -n -C2 'extractCompetitionEvent|event_type|type\s*:' "$f"
done

Repository: BrianCLong/summit

Length of output: 747


Fix field name mismatch: type should be event_type.

The schema defines event_type as the field name (src/graphrag/schema/competitionEvent.ts, line 4), but the connector returns type (src/connectors/rest/regulatoryNews.ts, line 7). This contract violation will break validation and ingestion. Rename the field to event_type to match the schema.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/connectors/rest/regulatoryNews.ts` around lines 5 - 8, The returned
object in the regulatory news connector is using the wrong field name "type"
which must be renamed to "event_type" to match the schema; update the return
value (the object that includes id: hash, type: "REGULATORY_COMPETITION_EVENT",
actors: []) to replace the "type" property with "event_type" (event_type:
"REGULATORY_COMPETITION_EVENT") so that the output of the regulatoryNews
connector conforms to the competition event schema and passes validation.

import type { EvidenceReport } from '../evidence/types.js';

export interface CompetitionEvent extends EvidenceReport {
event_type: 'REGULATORY_COMPETITION_EVENT';
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Use a single discriminant key across schema and extractor (type vs event_type).

CompetitionEvent uses event_type, but the regulatory extractor/test contract uses type. This creates a guaranteed shape mismatch for competition events and can break downstream classification/query logic.

Proposed fix
 export interface CompetitionEvent extends EvidenceReport {
-  event_type: 'REGULATORY_COMPETITION_EVENT';
+  type: 'REGULATORY_COMPETITION_EVENT';
   actors: string[];
   claims: string[];
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/graphrag/schema/competitionEvent.ts` at line 4, The schema uses
event_type but the regulatory extractor/test contract expects the discriminant
key type, causing a shape mismatch; update the CompetitionEvent schema to use
type: 'REGULATORY_COMPETITION_EVENT' (replace event_type) and search/rename any
references to event_type in related code/tests/extractors to use type so the
discriminant key is consistent with the regulatory extractor and downstream
consumers.

@@ -0,0 +1,57 @@
version: 1
item:
title: "TEMPLATE: Replace with ITEM title"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Replace template placeholders with competition-events bundle values.

This manifest is still wired to _template and subsumption-bundle-framework artifacts, so the competition-events bundle won’t resolve the correct claims/docs/fixtures.

Proposed fix
 item:
-  title: "TEMPLATE: Replace with ITEM title"
+  title: "Competition Events Subsumption Bundle"
@@
-item_slug: "_template"
+item_slug: "competition-events"
@@
 claim_registry:
   mode: "missing-item"
-  claims_file: "subsumption/_template/claims.md"
+  claims_file: "subsumption/competition-events/claims.md"
@@
 prs:
-  - title: "feat(governance): add subsumption bundle framework verifier"
+  - title: "feat(governance): add competition events subsumption bundle"
@@
 docs_targets:
-  - "docs/standards/subsumption-bundle-framework.md"
-  - "docs/security/data-handling/subsumption-bundle-framework.md"
-  - "docs/ops/runbooks/subsumption-bundle-framework.md"
+  - "docs/standards/competition-events.md"
+  - "docs/security/data-handling/competition-events.md"
+  - "docs/ops/runbooks/competition-events.md"
@@
 fixtures:
-  deny_policy_dir: "subsumption/_template/fixtures/policy/deny"
+  deny_policy_dir: "subsumption/competition-events/fixtures/policy/deny"
   tests:
     positive:
-      - "subsumption/_template/fixtures/tests/positive/minimal_bundle"
+      - "subsumption/competition-events/fixtures/tests/positive/minimal_bundle"
     negative:
-      - "subsumption/_template/fixtures/tests/negative/missing_docs"
+      - "subsumption/competition-events/fixtures/tests/negative/missing_docs"

Also applies to: 8-8, 12-12, 15-15, 35-37, 43-48

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@subsumption/competition-events/manifest.yaml` at line 3, The manifest still
contains template placeholders (e.g., title: "TEMPLATE: Replace with ITEM
title") and references to the `_template` and `subsumption-bundle-framework`
artifacts which prevent the competition-events bundle from resolving correct
claims/docs/fixtures; update the manifest.yaml to replace the TEMPLATE
placeholders with the real `competition-events` values and swap any `_template`
and `subsumption-bundle-framework` artifact references to the actual
competition-events artifact names used by this bundle (check fields around
title, any `artifact:` entries, `docs`, `fixtures`, and `claims` keys) so all
references point to the competition-events resources instead of the
template/framework ones.

Comment on lines +22 to +23
required_checks_status: "assumed"
deny_by_default_required: true
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid assumed check status when deny-by-default is required.

Using "assumed" for required checks/discovery weakens enforcement and can allow policy gates to pass without verified CI evidence.

Proposed hardening
 gates:
   - name: "verify-subsumption-bundle"
-    required_checks_status: "assumed"
+    required_checks_status: "required"
     deny_by_default_required: true
@@
 required_checks_discovery:
-  status: "assumed"
+  status: "required"
   instructions: "docs/required_checks.todo.md"

Also applies to: 56-57

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@subsumption/competition-events/manifest.yaml` around lines 22 - 23, The
manifest currently sets required_checks_status: "assumed" while
deny_by_default_required: true which weakens enforcement; change
required_checks_status to a non-assumed value (e.g., "required" or "enforced")
so the deny-by-default gate requires actual CI verification, and apply the same
change for the other occurrence mentioned (lines 56-57) to ensure both places
use the stricter status.

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.

1 participant