Skip to content

v1.5.0 — Fixes Pedning Details Assignment to Governance Provenance Chain

Choose a tag to compare

@greenarmor greenarmor released this 19 Jun 12:40
· 25 commits to master since this release

Release v1.5.0 (Minor)

This is a minor release. It introduces Fix Assignment to Governance Provenance Chain — a system that links every pending audit finding to an existing governance record, creating full operational traceability from finding to resolution. No breaking changes. Existing projects, governance records, and audit workflows continue to work unchanged.

Previous release: v1.4.3
Release date: 2026-06-19


Highlights

Fix Assignment to Governance Provenance Chain

Every pending fix produced by ges audit (via CLI or MCP server) can now be assigned to an existing governance record in the provenance chain. This closes the gap between what was found and who is responsible for fixing it, under what authority, and whether it's been resolved.

The core question it answers: "Who is fixing this finding? Under which governance record was it approved? Who assigned them? Has it been resolved, and how?"

Audit Finding (SECRETS-001 in auth.ts:42)
  │
  ▼
  Assigned to Governance Record (gov-123, "Customer Support Chatbot")
    ├── Approved by: Jane Doe, CISO, under AI Ethics Board
    ├── Policy: GDPR Art. 32, Internal Security Policy v2.1
    ├── Risk: High (7.5/10), mitigated by encryption
    ├── Evidence: Jira SEC-123
    ├── Assignee: Bob Smith, Security Engineer
    ├── Assigned by: Tech Lead
    └── Status: assigned → in-progress → fixed → verified

Key Metrics

Metric Before (v1.4.3) After (v1.5.0)
MCP tools 43 46 (+3 fix-assignment)
CLI commands 15 16 (+ges assign)
Dashboard API endpoints 18 22 (+4 fix-assignment)
Tests passing 422 465 (+43)
New storage file .ges/fix-assignments.json

What's New

1. Core Storage Module

New file: .ges/fix-assignments.json — separate from governance records (fixes are operational, governance is stable).

12 functions in packages/core/src/fix-assignments/index.ts:

Function Purpose
loadFixAssignments() Read all assignments from disk
saveFixAssignments() Persist assignments
createFixAssignment() Factory function with full finding + governance metadata
addFixAssignment() Upsert by finding key (same finding reassigned replaces)
updateFixAssignment() Partial update by ID
updateFixAssignmentStatus() Change status (assigned → in-progress → fixed → verified)
findFixAssignment() Lookup by finding key
findFixAssignmentById() Lookup by assignment ID
findFixAssignmentsForRecord() All assignments for a governance record
resolveFixAssignment() Mark as fixed with resolution details (who, how, notes)
deleteFixAssignment() Remove by ID
unassignFix() Remove by finding key

Stable finding key: ${ruleId}:${file}:${line} — survives re-audits, allows tracking the same finding across multiple audit runs.

2. Fix Assignment Data Model

Each assignment captures the full chain from finding to governance to resolution:

interface FixAssignment {
  id: string;                    // fa-{timestamp}-{counter}
  finding_key: string;           // "SECRETS-001:src/auth.ts:42"
  finding_rule_id: string;
  finding_title: string;
  finding_file: string;
  finding_line?: number;
  finding_severity: SeverityLevel;
  finding_control_ids: string[]; // GDPR-ART32-002, OWASP-AUTH-001
  governance_record_id: string;  // links to GovernanceRecord
  governance_system_name: string;
  assignee: string;
  assignee_role: string;
  assigned_at: string;
  assigned_by: string;
  status: "assigned" | "in-progress" | "fixed" | "verified" | "rejected";
  notes: string;
  resolution: null | {
    resolved_at: string;
    resolved_by: string;
    resolved_by_role: string;
    method: "auto-fix" | "manual" | "not-applicable";
    resolution_notes: string;
  };
  created_at: string;
  updated_at: string;
}

3. Dashboard — Full UI Integration

The web dashboard now provides a complete assign-and-track workflow directly from the Fixes Detail and Traceability tabs:

Per-finding rendering:

  • Unassigned findings show a "+ Assign to Governance Record" button
  • Assigned findings show:
    • Status badge (assigned / in-progress / fixed / verified) with color coding
    • Linked governance record name
    • Assignee name and role
    • Resolution details (if resolved)
    • "Mark Fixed" button (if not yet resolved)
    • "Unassign" button

Assign modal — opens when clicking "+ Assign":

  • Governance record dropdown (filtered to existing records with status/risk display)
  • Assignee name (required) and role
  • Assignment notes
  • Actor attribution fields (your name + role for the audit trail)

Resolution flow — clicking "Mark Fixed" prompts for:

  • Resolver name and role
  • Resolution method (auto-fix / manual / not-applicable)
  • Resolution notes

Summary stats — new "Assigned" count card in the fixes summary grid.

Toast notifications — success/error feedback on all mutations, with auto-reload.

4. Dashboard API Endpoints (4 new)

Method Endpoint Purpose
GET /api/fix-assignments List all assignments
POST /api/fix-assignments/assign Create/upsert an assignment
POST /api/fix-assignments/resolve Mark assignment as fixed
POST /api/fix-assignments/:key/unassign Remove assignment by finding key

All POST endpoints:

  • Validate required fields (400 on missing data)
  • Validate governance record exists (404 on unknown record)
  • Record activity log entries with fix_assign / fix_resolve actions
  • Support actor attribution (actor_name / actor_role)

5. CLI Command — ges assign

New command for terminal-based assignment workflows:

# Assign a finding to a governance record
ges assign \
  --finding "SECRETS-001:src/auth.ts:42" \
  --record "gov-123" \
  --assignee "Bob Smith" \
  --assignee-role "Security Engineer" \
  --notes "Urgent — production key exposure" \
  --actor "Jane Doe" --actor-role "Tech Lead"

# List all assignments
ges assign --list

# Resolve an assignment
ges assign \
  --resolve "SECRETS-001:src/auth.ts:42" \
  --by "Bob Smith" --by-role "Security Engineer" \
  --method manual \
  --resolution-notes "Replaced hardcoded key with env var"

Interactive mode (no flags): Shows a finding picker with [ASSIGNED] markers, governance record picker, and assignee prompts.

Flags:

Flag Purpose
--finding <key> Finding key to assign
--record <id> Governance record ID or system name
--assignee <name> Person assigned
--assignee-role <role> Role of assignee
--notes <notes> Assignment context
--actor <name> Who is making the assignment (audit trail)
--actor-role <role> Role of the actor
--list List all assignments
--resolve <key> Resolve an assignment
--by <name> Who resolved it
--by-role <role> Role of resolver
--method <method> auto-fix / manual / not-applicable
--resolution-notes <notes> Resolution details

6. MCP Tools (3 new, 43 → 46 total)

Tool Description
assign_fix_to_governance Assign a finding to a governance record
list_fix_assignments List all assignments (optional filter by record ID)
resolve_fix_assignment Resolve an assignment with resolution details

All tools accept actor_name / actor_role for activity log attribution.

7. Activity Log Integration

Two new activity actions:

  • fix_assign — Recorded when a finding is assigned or unassigned
  • fix_resolve — Recorded when a finding is marked as resolved

Both appear in the dashboard Activity Log with full details (finding key, governance record, assignee, method).


End-to-End Workflow

# 1. Run an audit (produces findings)
ges audit
# → 5 findings found (2 critical, 2 high, 1 medium)

# 2. Create a governance record (if not already existing)
ges governance add --name "Payment API" --type api --risk high
ges governance approve <id> --approver "Jane" --role "CISO" --decision approved

# 3. Assign each finding to the governance record
ges assign --finding "SECRETS-001:src/auth.ts:42" --record <id> --assignee "Bob" --assignee-role "Security Engineer"

# 4. Fix the issue (manually or via ges fix)

# 5. Resolve the assignment
ges assign --resolve "SECRETS-001:src/auth.ts:42" --by "Bob" --by-role "Security Engineer" --method manual --resolution-notes "Replaced with env var"

# 6. Verify via dashboard
ges dashboard
# → Fixes tab shows: ✓ FIXED, resolver: Bob, method: manual

Via MCP (AI assistant):

User: "Assign the hardcoded key finding to the Payment API governance record, assigned to Bob Smith"
AI: [calls assign_fix_to_governance] → "Assigned SECRETS-001 to Payment API (gov-123), assignee: Bob Smith"

User: "List all fix assignments"
AI: [calls list_fix_assignments] → "3 assignments: 1 fixed, 2 pending"

User: "Mark the auth key finding as resolved"
AI: [calls resolve_fix_assignment] → "Resolved via manual fix by dashboard"

Via Dashboard:

  1. Open Fixes Detail tab
  2. Each pending finding shows "+ Assign to Governance Record"
  3. Click → select governance record → enter assignee → save
  4. Assigned findings show status badge, linked record, assignee
  5. Click "Mark Fixed" when resolved → enter resolution details

Architecture

Separation of Concerns

Fix assignments are stored separately from governance records (.ges/fix-assignments.json vs .ges/governance-records.json):

  • Governance records are stable approval artifacts — they don't change every time a finding is assigned
  • Fix assignments are operational — they track day-to-day remediation work
  • The link between them is governance_record_id, allowing many findings to map to one governance record

Upsert by Finding Key

Assigning the same finding twice (same ruleId:file:line) replaces the previous assignment rather than creating duplicates. This allows reassignment without cleanup.

Stable Finding Keys

The key format ${ruleId}:${file}:${line} is deterministic — running ges audit twice produces the same keys for the same findings, allowing assignments to persist across re-audits.


Files Changed

File Change
packages/core/src/types/index.ts FixAssignment, FixAssignmentStatus types + 2 new ActivityAction values
packages/core/src/fix-assignments/index.ts New — 12 storage functions
packages/core/src/index.ts Export fix-assignments module
packages/core/src/index.test.ts +33 tests (create, load, resolve, unassign, upsert, lookup)
packages/web-dashboard/src/index.ts 4 API endpoints + fixAssignments in DashboardData
packages/web-dashboard/src/template.ts Assign modal, status badges, buttons, JS functions, summary stat
packages/web-dashboard/src/index.test.ts +10 API endpoint tests
packages/cli/src/commands/assign.ts Newges assign command with flags + interactive mode
packages/cli/src/cli.ts Register assign command
packages/mcp-server/src/server.ts 3 new MCP tools (46 total)
packages/mcp-server/src/server.test.ts Tool count assertion (43 → 46)

Test Results

Packages:    16 buildable, all clean
Tests:        465 passing (was 422, +43)

New tests:
  - 33 core fix-assignment tests (create, load, save, update, resolve, unassign, upsert, lookup)
  - 10 dashboard API endpoint tests (assign, resolve, unassign, validation, upsert)

E2E smoke test:
  - Dashboard renders assign buttons on unassigned findings ✓
  - Dashboard renders status badge + Mark Fixed + Unassign on assigned findings ✓
  - Assign modal opens with governance record dropdown ✓
  - Assignee name, role, linked record displayed correctly ✓

Upgrade Guide

This release is fully backward compatible. No migration steps required.

To start using fix assignments:

# Update to latest
npm install -g @greenarmor/ges@latest

# Run an audit to get findings
ges audit

# Assign findings to governance records
ges assign --finding "<ruleId>:<file>:<line>" --record <gov-id> --assignee "<name>"

If you use the MCP server:

npm install -g @greenarmor/ges-mcp-server@latest

The dashboard updates automatically — no configuration needed.


What's Next

  • npm publish of v1.5.0 (manual with OTP)
  • GitHub release with these notes
  • Dashboard UI enhancement: filter fix assignments by governance record, assignee, or status
  • Bulk assign: select multiple findings and assign to one record
  • Auto-suggest governance records based on finding control IDs
  • Integration with ges fix — automatically resolve assignments when auto-fix is applied