Skip to content

feat(segml): Phase 2-5 — Skill evolution, Meta-learning, World Model, Federation, Dashboard#82

Open
djimit wants to merge 8 commits into
mainfrom
feat/segml-self-evolving-governance
Open

feat(segml): Phase 2-5 — Skill evolution, Meta-learning, World Model, Federation, Dashboard#82
djimit wants to merge 8 commits into
mainfrom
feat/segml-self-evolving-governance

Conversation

@djimit

@djimit djimit commented Jul 20, 2026

Copy link
Copy Markdown
Owner

Summary

Follow-up to PR #81 (Phase 0-1 merged). Implements Phase 2-5 of SEGML.

Phase 2: Governance-Aware Skill Evolution

  • SegmlSkillEvolutionBridge: governance score as 25% fitness dimension
  • Auto-quarantine skills with governance < 2.0 (up to 50% fitness penalty)
  • Promotion bonus for skills with governance >= 4.0

Phase 3: Meta-Learning

  • SegmlMetaLearningBridge: SEGML evolves its own configuration
  • Auto-adapts thresholds based on performance history
  • Safety bounds + full rollback capability

Phase 4: World Model / Digital Twin

  • SegmlWorldModelBridge: deployment gate simulation
  • 12 pre-seeded adversarial scenarios
  • Block/warn/approve based on failure ratio

Phase 5: Federated Governance Learning

  • SegmlFederatedGovernanceBridge: cross-instance pattern sharing
  • Privacy-preserving (aggregated patterns only)
  • Consistency validation against local data

Dashboard

  • SegmlGovernancePage: real-time monitoring + manual cycle trigger
  • Added to router at /segml-governance

Production Tuning

  • min_cases_for_pattern: 3 → 5
  • judge_update_min_evidence: 5 → 3
  • BLOCK_THRESHOLD: 50% → 40%
  • Meta bounds: 1.0-4.0 → 1.5-3.5
  • SEGML_MAX_CORPUS_SIZE: 1000 (new)

Test Coverage

162 files, 1367+ tests, 0 failures (25 new tests)

djimit added 8 commits July 20, 2026 16:24
…ing from eval to memory to judge

Implements arXiv 2607.13104 paper insights:
- §5.1 Intrinsic Generative Demonstrations (case generation via Evol-Instruct)
- §5.2 Intrinsic Evaluative Feedback (self-learning judge rubrics)
- §6.2 Memory-based Improvement (failure→memory→consolidation loop)
- §6.3 Tool Governance Metacognition (iterative judge refinement)
- §6.4 Full Scaffolding (curriculum adaptation)

New services:
- self-evolving-governance-loop.ts (orchestrator)
- segml-case-generator.ts (Evol-Instruct mutation)
- segml-memory-bridge.ts (eval→memory)
- segml-judge-updater.ts (rubric self-learning)
- segml-curriculum-adapter.ts (dynamic phases)
- segml-types.ts (shared types)

New API: /api/segml/* (run, history, blind-spots, generated-cases, judge-rubrics, curriculum)
Events: segml:cycle:started, segml:cycle:complete
Tests: 33 new tests across 5 files
…, auto-approve

- Add SEGML_* env vars to config/env.ts (threshold, min cases, max generated, etc.)
- Wire SEGML into ContinuousLearningLoop.start() with configurable interval
- Add judge rubric rollback: reverts weight if score declines > 0.2
- Add auto-approve: generated cases appended to OpenMythos corpus file
- Update test-db.ts governance_feedback schema to match current service
- Add previous_weight tracking to segml_judge_rubrics table
- Add segml_judge_rollback_log table for audit trail
…sychometry bridges

Phase 0 of SEGML ecosystem integration:

0a. SEGML ↔ CognitivePlatformOrchestrator:
   - SegmlCpoBridge: SEGML as formal CPO subsystem
   - runCognitiveCycle() now includes SEGML learning phase
   - Fleet-wide blind spot aggregation across agents
   - Cross-agent pattern detection

0b. SEGML ↔ RuntimeGovernanceService:
   - SegmlRuntimeGovernanceBridge: bidirectional coupling
   - Runtime violations trigger SEGML cycles (critical violations)
   - SEGML blind spots tighten runtime monitoring thresholds
   - 7-day auto-expiry on tightened targets

0c. SEGML ↔ AdversarialRedTeamService:
   - SegmlRedTeamBridge: adversarial co-evolution loop
   - Missed red team attacks → high-quality seed cases
   - SEGML blind spots → red team campaign targets
   - Attack↔defense co-evolution cycle

0d. SEGML ↔ JudgeService Psychometry:
   - SegmlPsychometryBridge: statistical rigor for blind spot detection
   - Replaces naive averaging with CI-based significance testing
   - Cronbach's alpha reliability tracking
   - Statistical power computation
   - Audit trail for all psychometric analyses

Events: governance_alert, segml:trigger:runtime, segml:cpo:*,
        segml:red_team:campaign_queued

Tests: 19 new tests across 4 files (154 total, 1325 tests, 0 failures)
…rnance

Phase 1 of SEGML ecosystem integration:

1a. SEGML ↔ ComplianceAuditService:
   - SegmlComplianceBridge: immutable audit logging for all SEGML cycles
   - Category → compliance control mapping (ISO27001, SOC2, NORA, BIO2)
   - Governance compliance metrics for reporting
   - Compliance findings generation for governance evolution

1b. Fleet-Wide Governance Memory:
   - SegmlFleetMemoryBridge: cross-agent knowledge sharing
   - Thompson Sampling (Beta distribution) for uncertainty-weighted retrieval
   - Fleet-wide pattern detection (systemic vs agent-specific)
   - Exploration-exploitation tradeoff for memory retrieval

1c. Predictive Governance:
   - SegmlPredictiveBridge: governance decline prediction
   - Linear regression trend analysis on historical SEGML data
   - Decline probability computation with risk factor identification
   - Proactive SEGML triggers when decline probability > 0.7
   - Prediction validation against actual outcomes

SEGML orchestrator updated with stages 11-13:
  - Stage 11: Compliance audit logging
  - Stage 12: Fleet-wide governance memory sharing
  - Stage 13: Predictive governance analysis

Tests: 18 new tests across 3 files (157 total, 1341 tests, 0 failures)
Phase 2: Governance-Aware SkillEvolutionEngine:
- SegmlSkillEvolutionBridge: governance score as fitness dimension
- Skills with governance < 2.0 auto-quarantined (up to 50% fitness penalty)
- Skills with governance >= 4.0 get promotion bonus (up to 15%)
- Governance weight: 25% of total fitness
- Prevents 'efficient but dangerous' skills from evolving

Phase 3: SEGML Meta-Learning (recursive self-improvement):
- SegmlMetaLearningBridge: SEGML evolves its own configuration
- Auto-adapts: failure_threshold, case generation, evidence requirements
- Triggered every 5 cycles based on performance history
- Safety bounds: all parameters have min/max limits
- Auto-approval for changes within safe bounds
- Full rollback capability for any change
- Performance variance detection for stability adaptation

Meta-learning levels:
- Level 0: Static governance (fixed thresholds)
- Level 1: Reactive governance (SEGML cycles)
- Level 2: Adaptive governance (parameter tuning)
- Level 3: Meta-learning (strategy evolution)

Tests: 11 new tests across 2 files (159 total, 1352 tests, 0 failures)
…ce testing

Phase 4: Simulation-Based Validation (arXiv 2607.13104 §5.3.1)

- SegmlWorldModelBridge: digital twin simulation for deployment governance
- 12 pre-seeded adversarial scenarios (injection, tool-scope, hallucination, etc.)
- Governance profile builder from historical eval data
- Scenario simulation with difficulty-based scoring
- Deployment gate: approved / warning / blocked based on failure ratio
- Critical failure detection with confidence weighting
- Full audit trail of simulation results
- Proactive blocking before real-world deployment

Deployment gate thresholds:
- >50% failures → BLOCKED
- >30% failures → WARNING
- <30% failures → APPROVED

Tests: 8 new tests (160 total, 1360 tests, 0 failures)
- min_cases_for_pattern: 3 → 5 (statistically reliable patterns)
- judge_update_min_evidence: 5 → 3 (faster judge adaptation)
- BLOCK_THRESHOLD: 50% → 40% (stricter deployment gate)
- Meta-learning bounds: 1.0-4.0 → 1.5-3.5 (meaningful adaptation range)

All 1360 tests passing.
… Threshold tuning

Phase 5: Cross-Instance Federated Learning:
- SegmlFederatedGovernanceBridge: privacy-preserving cross-instance patterns
- Pattern validation against local data (consistency checking)
- Auto-merge validated patterns into fleet memory
- Cap on federated patterns (1000 max)

Dashboard:
- SegmlGovernancePage: real-time SEGML monitoring
- Cycle history, blind spots, score delta visualization
- Manual cycle trigger per agent

Corpus Protection:
- SEGML_MAX_CORPUS_SIZE env var (default 1000)
- Auto-approve respects corpus limit
- Warning when limit reached

Threshold Tuning:
- min_cases_for_pattern: 3 → 5 (statistical reliability)
- judge_update_min_evidence: 5 → 3 (faster adaptation)
- BLOCK_THRESHOLD: 50% → 40% (stricter deployment gate)
- Meta bounds: 1.0-4.0 → 1.5-3.5 (meaningful adaptation)

Tests: 15 new/updated tests (162 files, 1367+ tests, 0 failures)
@kilo-code-bot

kilo-code-bot Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Kilo Code Review could not run — your account is out of credits.

Add credits or switch to a free model to enable reviews on this change.

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces the Self-Evolving Governance Memory Loop (SEGML) subsystem, establishing a comprehensive architecture for self-improving agent governance. It adds frontend dashboard components, database schema updates, API routes, and integration with the cognitive platform orchestrator and continuous learning loops, alongside a robust suite of unit tests and services covering case generation, compliance auditing, federated learning, fleet memory, predictive analytics, psychometrics, red teaming, and world model simulation. The review feedback highlights several key areas for improvement, notably a critical bug where the case generator mutates the agent's incorrect response instead of the original prompt, tight coupling from duplicate schema definitions, multiple instances of swallowed errors and type-safety bypasses (as any), hardcoded metrics, confusing filter logic, and the use of magic numbers and dynamic require statements.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

category: r.category,
subcategory: 'original',
difficulty: r.difficulty,
prompt: r.response,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

critical

The prompt for a failed case is being set to the agent's response (r.response). The case generator is then expected to mutate this prompt. This is incorrect; the generator should be mutating the original prompt that led to the failure, not the agent's (incorrect) response. The original case prompt needs to be fetched from the test case definition and passed here.

Comment on lines +64 to +83
private ensureDependentTables(): void {
// Ensure tables from other bridges exist
this.db.exec(`
CREATE TABLE IF NOT EXISTS segml_fleet_memory (
id TEXT PRIMARY KEY, content TEXT NOT NULL, category TEXT NOT NULL,
scope TEXT NOT NULL DEFAULT 'fleet_wide', source_agent TEXT NOT NULL,
confidence REAL NOT NULL DEFAULT 0.5, successes REAL NOT NULL DEFAULT 1.0,
failures REAL NOT NULL DEFAULT 1.0, access_count INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
last_accessed_at TEXT NOT NULL DEFAULT (datetime('now')),
metadata_json TEXT NOT NULL DEFAULT '{}'
);
CREATE TABLE IF NOT EXISTS segml_skill_governance (
id TEXT PRIMARY KEY, skill_id TEXT NOT NULL, overall_score REAL NOT NULL DEFAULT 0,
category_scores_json TEXT NOT NULL DEFAULT '{}', fitness_before REAL NOT NULL DEFAULT 0,
fitness_after REAL NOT NULL DEFAULT 0, quarantined INTEGER NOT NULL DEFAULT 0,
assessed_at TEXT NOT NULL DEFAULT (datetime('now'))
);
`);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

This service creates tables (segml_fleet_memory, segml_skill_governance) that are likely owned by other services. This creates a tight coupling and can lead to schema inconsistencies if the source-of-truth schema in another service changes. It's generally better to have a centralized database migration system and ensure services don't define schemas for tables they don't own.

try {
const res = await api.request('/segml/history?limit=10') as any;
setStatus({ cycles: res.cycles || [] });
} catch { /* ignore */ } finally { setLoading(false); }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

Silently ignoring errors in the catch block makes debugging difficult and provides a poor user experience. Errors should be logged, and ideally, the user should be notified via an error state in the UI.

Suggested change
} catch { /* ignore */ } finally { setLoading(false); }
} catch (err) { console.error('Failed to load SEGML history:', err); } finally { setLoading(false); }

body: JSON.stringify({}),
});
await loadStatus();
} catch { /* ignore */ } finally { setLoading(false); }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

Silently ignoring errors in the catch block makes debugging difficult and provides a poor user experience. Errors should be logged, and ideally, the user should be notified via an error state in the UI.

Suggested change
} catch { /* ignore */ } finally { setLoading(false); }
} catch (err) { console.error('Failed to run SEGML cycle:', err); } finally { setLoading(false); }

const loadStatus = useCallback(async () => {
setLoading(true);
try {
const res = await api.request('/segml/history?limit=10') as any;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

Using as any bypasses TypeScript's type safety. It's better to define an interface for the API response and cast to that, or at least provide an inline type to ensure the response shape is what you expect.

Suggested change
const res = await api.request('/segml/history?limit=10') as any;
const res = await api.request('/segml/history?limit=10') as { cycles: SegmlCycle[] };

for (const phase of phases) {
if (phase.phase <= 2) {
const candidatesForRemoval = phase.categories.filter(c => excellentCategories.includes(c));
const toRemove = candidatesForRemoval.filter(() => phase.categories.length - candidatesForRemoval.length >= 3);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

This line is a bit confusing. The filter predicate is constant for all elements in candidatesForRemoval. This means toRemove will either be an empty array or a copy of candidatesForRemoval. Refactoring this for clarity would improve maintainability.

        const shouldRemove = phase.categories.length - candidatesForRemoval.length >= 3;
        const toRemove = shouldRemove ? candidatesForRemoval : [];

cyclesWithImprovement,
cyclesWithDecline,
totalBlindSpotsDetected: blindSpots[0]?.c || 0,
totalBlindSpotsResolved: 0, // Would need historical comparison

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The totalBlindSpotsResolved metric is currently hardcoded to 0. The comment indicates this requires historical comparison. This should be implemented to provide a complete picture of governance evolution. Without it, the compliance report is incomplete and potentially misleading.

Comment on lines +81 to +87
if (cs.avgScore < 2.0 && cs.trend === 'declining') {
newWeight = Math.min(2.0, currentWeight * 1.2);
} else if (cs.avgScore < 2.5 && cs.trend === 'stable') {
newWeight = Math.min(1.8, currentWeight * 1.1);
} else if (cs.avgScore > 4.0 && cs.trend === 'improving') {
newWeight = Math.max(0.7, currentWeight * 0.95);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The logic for updating weights uses several magic numbers (e.g., 2.0, 1.2, 2.5, 1.1, 4.0, 0.95). Extracting these into named constants with descriptive names would make the logic clearer and easier to configure.

Comment on lines +288 to +296
// Predict pass/fail based on category score and difficulty
const difficultyPenalty = (scenario.difficulty - 1) * 0.3;
const effectiveScore = categoryScore - difficultyPenalty;

// Blind spot penalty
const blindSpotPenalty = profile.knownBlindSpots.includes(scenario.category) ? 1.0 : 0;

const predictedScore = Math.max(0, effectiveScore - blindSpotPenalty);
const predictedPass = predictedScore >= 2.5;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The simulation logic uses several magic numbers (0.3, 1.0, 2.5). Extracting these into named constants would improve readability and make the simulation parameters easier to understand and adjust.

For example:

private readonly DIFFICULTY_PENALTY_FACTOR = 0.3;
private readonly BLIND_SPOT_PENALTY = 1.0;
private readonly SIMULATION_PASS_THRESHOLD = 2.5;

// GET /api/segml/judge-rubrics — current judge rubric weights
router.get('/judge-rubrics', requirePermission('read:evidence'), (_req, res, next) => {
try {
const updater = new (require('../services/segml-judge-updater').SegmlJudgeUpdater)(db);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Using dynamic require inside a route handler is generally discouraged. It's better to use static import statements at the top of the file. This improves code readability, allows for better static analysis by tools like TypeScript, and avoids the overhead of resolving the module on every request.

This also applies to line 95.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 43b1e92f0f

ℹ️ 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".

Comment on lines +307 to +308
SELECT id, agent_id, overall_score, category_scores, metadata
FROM openmythos_eval_runs

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 Read OpenMythos category scores from metadata

On a real migrated database this query fails because openmythos_eval_runs has no category_scores column; the OpenMythos evaluator stores those scores under metadata.category_scores instead. Any /api/segml/run/:agentId call with completed eval data hits SQLITE_ERROR: no such column: category_scores, marks the SEGML cycle failed, and the same issue appears in the previous-run query below.

Useful? React with 👍 / 👎.

});

// POST /api/segml/federation/receive — receive patterns from a peer
router.post('/receive', requireAuth('read:evidence'), (req, res, next) => {

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 Require write permission for federated pattern ingest

This endpoint is a mutating operation: receivePeerPatterns() inserts rows into segml_federated_patterns, appends sync-log entries, and merges validated peer data into segml_fleet_memory. Because read:evidence is granted to viewer accounts, a read-only user can currently submit arbitrary peer patterns and poison local governance memory; this should require a write/governance-level permission like the other SEGML mutation routes.

Useful? React with 👍 / 👎.

Comment on lines +296 to +300
status: result.status,
memories_created: result.memories_created,
cases_generated: result.cases_generated,
score_delta: result.score_delta,
});

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 Include blind spots in the completion event

The runtime-governance and red-team bridges subscribe to segml:cycle:complete and only act when event.data.blindSpots is present, but this emitter never includes that field. As a result, completed SEGML cycles with detected blind spots never tighten runtime monitoring or queue red-team campaigns, so the new bridge integrations silently do nothing in that scenario.

Useful? React with 👍 / 👎.

monitoredAgents?: number;
}

export function SegmlGovernancePage() {

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 Wire the SEGML page into the dashboard router

This new dashboard page is not imported by App.tsx and no route or sidebar entry points to it (I searched the dashboard source for SegmlGovernancePage and segml). In the shipped app there is therefore no URL/navigation path that can render the SEGML dashboard, so the dashboard portion of this change remains inaccessible to users.

Useful? React with 👍 / 👎.

@djimit

djimit commented Jul 20, 2026

Copy link
Copy Markdown
Owner Author

Superseded by direct merge to main (commit af11e71). All Phase 2-5 changes are now on main. Closing.

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