Skip to content

Commit 217c92b

Browse files
committed
feat: add segregation of duties schema, types, and spec
Add the `segregation_of_duties` subsection to the compliance schema with support for roles, conflict matrix, assignments, isolation levels, handoff workflows, and enforcement modes. - JSON Schema definition in agent-yaml.schema.json - TypeScript types in loader.ts ComplianceConfig interface - Spec documentation including DUTIES.md convention, validation rules, and regulatory reference table Closes #10 (part 1 of 4)
1 parent 3323932 commit 217c92b

File tree

3 files changed

+216
-1
lines changed

3 files changed

+216
-1
lines changed

spec/SPECIFICATION.md

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
The standard is designed to be:
1010
- **Framework-agnostic** — works with Claude Code, OpenAI, LangChain, CrewAI, AutoGen, and others
1111
- **Git-native** — version control, branching, diffing, and collaboration built in
12-
- **Compliance-ready** — first-class support for FINRA, Federal Reserve, and interagency regulatory requirements
12+
- **Compliance-ready** — first-class support for FINRA, Federal Reserve, interagency regulatory requirements, and segregation of duties
1313
- **Composable** — agents can extend, depend on, and delegate to other agents
1414

1515
## 2. Directory Structure
@@ -19,6 +19,7 @@ my-agent/
1919
├── agent.yaml # [REQUIRED] Agent manifest
2020
├── SOUL.md # [REQUIRED] Identity and personality
2121
├── RULES.md # Hard constraints and boundaries
22+
├── DUTIES.md # Segregation of duties policy and role declaration
2223
├── AGENTS.md # Framework-agnostic fallback instructions
2324
├── README.md # Human documentation
2425
├── skills/ # Reusable capability modules
@@ -194,6 +195,48 @@ compliance:
194195
soc_report_required: false # SOC 2 report required
195196
vendor_ai_notification: true # Vendor must notify of AI changes
196197
subcontractor_assessment: false # Fourth-party risk assessed
198+
199+
# Segregation of duties (multi-agent duty separation)
200+
segregation_of_duties:
201+
roles: # Define roles for agents (min 2)
202+
- id: maker # Initiates/creates
203+
description: Creates proposals and initiates actions
204+
permissions: [create, submit]
205+
- id: checker # Reviews/approves
206+
description: Reviews and approves maker outputs
207+
permissions: [review, approve, reject]
208+
- id: executor # Executes approved work
209+
description: Executes approved actions
210+
permissions: [execute]
211+
- id: auditor # Audits completed work
212+
description: Reviews completed actions for compliance
213+
permissions: [audit, report]
214+
215+
conflicts: # SOD conflict matrix
216+
- [maker, checker] # Maker cannot approve own work
217+
- [maker, auditor] # Maker cannot audit own work
218+
- [executor, checker] # Executor cannot approve what they execute
219+
- [executor, auditor] # Executor cannot audit own execution
220+
221+
assignments: # Bind roles to agents
222+
loan-originator: [maker]
223+
credit-reviewer: [checker]
224+
loan-processor: [executor]
225+
compliance-auditor: [auditor]
226+
227+
isolation:
228+
state: full # full | shared | none
229+
credentials: separate # separate | shared
230+
231+
handoffs: # Critical actions requiring multi-role handoff
232+
- action: credit_decision
233+
required_roles: [maker, checker]
234+
approval_required: true
235+
- action: loan_disbursement
236+
required_roles: [maker, checker, executor]
237+
approval_required: true
238+
239+
enforcement: strict # strict | advisory
197240
```
198241
199242
### Example Minimal agent.yaml
@@ -365,6 +408,30 @@ For regulated agents, RULES.md should include explicit regulatory constraints:
365408
- Never transmit restricted data across jurisdictional boundaries
366409
```
367410

411+
## 5a. DUTIES.md — Segregation of Duties
412+
413+
Declares the agent's duties, role boundaries, and the system-wide SOD policy. DUTIES.md exists at two levels:
414+
415+
**Root level** (`DUTIES.md`) — Documents the system-wide segregation of duties policy: all roles, the conflict matrix, handoff workflows, isolation policy, and enforcement mode. This is the SOD equivalent of `RULES.md` — it defines the policy that all agents in the system must follow.
416+
417+
**Per-agent level** (`agents/<name>/DUTIES.md`) — Declares this specific agent's role, permissions, boundaries, and handoff participation. Each sub-agent's DUTIES.md answers: what is my role, what can I do, what must I not do, and who do I hand off to.
418+
419+
### Root DUTIES.md Recommended Sections
420+
421+
- **Roles** — Table of all roles, assigned agents, and permissions
422+
- **Conflict Matrix** — Which role pairs cannot be held by the same agent
423+
- **Handoff Workflows** — Step-by-step handoff chains for critical actions
424+
- **Isolation Policy** — State and credential isolation levels
425+
- **Enforcement** — Strict vs advisory mode
426+
427+
### Per-Agent DUTIES.md Recommended Sections
428+
429+
- **Role** — This agent's assigned role
430+
- **Permissions** — What actions this agent can take
431+
- **Boundaries** — Must/must-not rules specific to this role
432+
- **Handoff Participation** — Where this agent sits in handoff chains
433+
- **Isolation** — This agent's isolation constraints
434+
368435
## 6. AGENTS.md — Framework-Agnostic Instructions
369436

370437
Provides fallback instructions compatible with Cursor, Copilot, and other tools that read `AGENTS.md`. This file supplements `agent.yaml` + `SOUL.md` for systems that don't understand the gitagent format.
@@ -864,6 +931,13 @@ A valid gitagent repository must:
864931
5. All referenced tools must exist in `tools/`
865932
6. All referenced sub-agents must exist in `agents/`
866933
7. `hooks.yaml` scripts must exist at specified paths
934+
8. If `compliance.segregation_of_duties` is present:
935+
- `roles` must define at least 2 roles with unique IDs
936+
- `conflicts` pairs must reference defined role IDs
937+
- `assignments` must reference defined role IDs
938+
- No agent in `assignments` may hold roles that appear together in `conflicts`
939+
- `handoffs.required_roles` must reference defined role IDs and include at least 2
940+
- Assigned agents should exist in the `agents` section
867941

868942
## 19. CLI Commands
869943

@@ -942,6 +1016,15 @@ All schemas are in `spec/schemas/`:
9421016
| SR 21-8 | BSA/AML Model Risk | `compliance.model_risk` for AML agents |
9431017
| CFPB Circular 2022-03 | Adverse Action + AI | `compliance.data_governance.lda_search` |
9441018

1019+
### Segregation of Duties References
1020+
1021+
| Document | Subject | gitagent Impact |
1022+
|----------|---------|-----------------|
1023+
| FINOS AI Governance Framework | Multi-Agent Isolation & Segmentation | `compliance.segregation_of_duties` |
1024+
| SOC 2 Type II | Logical Access Controls | `segregation_of_duties.isolation` |
1025+
| SR 11-7 Section IV | Independent Review | `segregation_of_duties.conflicts` (maker/checker separation) |
1026+
| FINRA 3110 | Supervisory Systems (duty separation) | `segregation_of_duties.handoffs` |
1027+
9451028
---
9461029

9471030
*This specification is a living document. Contributions welcome.*

spec/schemas/agent-yaml.schema.json

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,9 @@
429429
},
430430
"vendor_management": {
431431
"$ref": "#/$defs/vendor_management_config"
432+
},
433+
"segregation_of_duties": {
434+
"$ref": "#/$defs/segregation_of_duties_config"
432435
}
433436
},
434437
"additionalProperties": false,
@@ -662,6 +665,116 @@
662665
}
663666
},
664667
"additionalProperties": false
668+
},
669+
670+
"segregation_of_duties_config": {
671+
"type": "object",
672+
"description": "Segregation of duties configuration for multi-agent systems. Ensures no single agent has complete control over critical processes.",
673+
"properties": {
674+
"roles": {
675+
"type": "array",
676+
"description": "Roles that agents can hold in this system",
677+
"items": {
678+
"type": "object",
679+
"required": ["id", "description"],
680+
"properties": {
681+
"id": {
682+
"type": "string",
683+
"pattern": "^[a-z][a-z0-9_]*$",
684+
"description": "Role identifier (snake_case)"
685+
},
686+
"description": {
687+
"type": "string",
688+
"description": "Human-readable role description"
689+
},
690+
"permissions": {
691+
"type": "array",
692+
"items": {
693+
"type": "string",
694+
"enum": ["create", "submit", "review", "approve", "reject", "execute", "audit", "report"]
695+
},
696+
"uniqueItems": true,
697+
"description": "Permissions granted to this role"
698+
}
699+
},
700+
"additionalProperties": false
701+
},
702+
"minItems": 2
703+
},
704+
"conflicts": {
705+
"type": "array",
706+
"description": "Pairs of role IDs that cannot be held by the same agent (SOD matrix)",
707+
"items": {
708+
"type": "array",
709+
"items": {
710+
"type": "string"
711+
},
712+
"minItems": 2,
713+
"maxItems": 2
714+
}
715+
},
716+
"assignments": {
717+
"type": "object",
718+
"description": "Maps agent names to their assigned roles",
719+
"additionalProperties": {
720+
"type": "array",
721+
"items": {
722+
"type": "string"
723+
},
724+
"minItems": 1
725+
}
726+
},
727+
"isolation": {
728+
"type": "object",
729+
"description": "Isolation level between agents with different roles",
730+
"properties": {
731+
"state": {
732+
"type": "string",
733+
"enum": ["full", "shared", "none"],
734+
"description": "'full': agents cannot access each other's state. 'shared': read-only cross-access. 'none': no isolation."
735+
},
736+
"credentials": {
737+
"type": "string",
738+
"enum": ["separate", "shared"],
739+
"description": "'separate': each role has its own credential scope. 'shared': agents share credentials."
740+
}
741+
},
742+
"additionalProperties": false
743+
},
744+
"handoffs": {
745+
"type": "array",
746+
"description": "Critical actions requiring multi-role participation",
747+
"items": {
748+
"type": "object",
749+
"required": ["action", "required_roles"],
750+
"properties": {
751+
"action": {
752+
"type": "string",
753+
"description": "Action type requiring handoff (e.g., credit_decision, loan_disbursement)"
754+
},
755+
"required_roles": {
756+
"type": "array",
757+
"items": { "type": "string" },
758+
"minItems": 2,
759+
"description": "Roles that must participate sequentially"
760+
},
761+
"approval_required": {
762+
"type": "boolean",
763+
"description": "Whether explicit approval is needed at each handoff",
764+
"default": true
765+
}
766+
},
767+
"additionalProperties": false
768+
}
769+
},
770+
"enforcement": {
771+
"type": "string",
772+
"enum": ["strict", "advisory"],
773+
"description": "'strict': SOD violations are errors. 'advisory': SOD violations are warnings.",
774+
"default": "strict"
775+
}
776+
},
777+
"additionalProperties": false
665778
}
666779
}
667780
}

src/utils/loader.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,25 @@ export interface ComplianceConfig {
115115
vendor_ai_notification?: boolean;
116116
subcontractor_assessment?: boolean;
117117
};
118+
segregation_of_duties?: {
119+
roles?: Array<{
120+
id: string;
121+
description: string;
122+
permissions?: string[];
123+
}>;
124+
conflicts?: Array<[string, string]>;
125+
assignments?: Record<string, string[]>;
126+
isolation?: {
127+
state?: string;
128+
credentials?: string;
129+
};
130+
handoffs?: Array<{
131+
action: string;
132+
required_roles: string[];
133+
approval_required?: boolean;
134+
}>;
135+
enforcement?: string;
136+
};
118137
}
119138

120139
export function loadAgentManifest(dir: string): AgentManifest {

0 commit comments

Comments
 (0)