v1.5.0 — Fixes Pedning Details Assignment to Governance Provenance Chain
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_resolveactions - 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 unassignedfix_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: manualVia 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:
- Open Fixes Detail tab
- Each pending finding shows "+ Assign to Governance Record"
- Click → select governance record → enter assignee → save
- Assigned findings show status badge, linked record, assignee
- 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 |
New — ges 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@latestThe 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