Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…se, supplier security, training, audit scheduling, security impact assessment Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
|
@copilot 仔细检查,避免和现有协议重复 |
…ums via shared schemas from security-context.zod.ts Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
已完成全面检查,发现并修复了以下重复项(9bc437c): 已去重:
确认无概念重叠:
|
There was a problem hiding this comment.
Pull request overview
Adds ISO 27001:2022 organization-level compliance governance schemas to packages/spec/src/system, extending the spec’s security/compliance protocol coverage (incident response, supplier security, training, and audit governance) and deduplicating shared security enums.
Changes:
- Introduces new Zod protocols + tests for incident response (A.5.24–A.5.28), supplier security (A.5.19–A.5.22), and training (A.6.3).
- Extends compliance governance with audit scheduling + finding lifecycle (A.5.35) and change-management with security impact assessment (A.8.32).
- Extracts canonical shared enums (
DataClassificationSchema,ComplianceFrameworkSchema) and updates system barrel exports + roadmap.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/spec/src/system/training.zod.ts | Adds training course/record/plan schemas (A.6.3). |
| packages/spec/src/system/training.test.ts | Adds validation coverage for training schemas. |
| packages/spec/src/system/supplier-security.zod.ts | Adds supplier assessment + policy schemas (A.5.19–A.5.22). |
| packages/spec/src/system/supplier-security.test.ts | Adds validation coverage for supplier security schemas. |
| packages/spec/src/system/security-context.zod.ts | Defines canonical shared enums for classification + frameworks and reuses them in existing schemas. |
| packages/spec/src/system/index.ts | Re-exports new system protocols from the barrel. |
| packages/spec/src/system/incident-response.zod.ts | Adds incident lifecycle + notification/policy schemas (A.5.24–A.5.28). |
| packages/spec/src/system/incident-response.test.ts | Adds validation coverage for incident response schemas. |
| packages/spec/src/system/compliance.zod.ts | Adds audit schedule + finding schemas and wires them into ComplianceConfig (A.5.35). |
| packages/spec/src/system/compliance.test.ts | Adds validation coverage for audit schedules/findings and config integration. |
| packages/spec/src/system/change-management.zod.ts | Adds securityImpact assessment block to ChangeRequest (A.8.32). |
| packages/spec/src/system/change-management.test.ts | Adds validation coverage for change request security impact. |
| ROADMAP.md | Tracks ISO 27001 schema coverage status and remaining work. |
| /** | ||
| * Retention period for incident records in days | ||
| */ | ||
| retentionDays: z.number().default(2555) |
There was a problem hiding this comment.
retentionDays should not accept negative (or non-integer) values, but it’s currently z.number().default(2555). Consider constraining it to a positive integer (e.g., .int().min(1)) to avoid validating impossible retention policies.
| retentionDays: z.number().default(2555) | |
| retentionDays: z.number().int().min(1).default(2555) |
| /** | ||
| * Reassessment interval in days | ||
| */ | ||
| reassessmentIntervalDays: z.number().default(365) |
There was a problem hiding this comment.
reassessmentIntervalDays is an interval but is currently unconstrained (z.number().default(365)), so negative or fractional values validate. Consider restricting it to a positive integer (e.g., .int().min(1)) to keep supplier policy configs valid.
| reassessmentIntervalDays: z.number().default(365) | |
| reassessmentIntervalDays: z.number().int().min(1).default(365) |
| /** | ||
| * Training completion date (Unix milliseconds) | ||
| */ | ||
| completedAt: z.number().optional().describe('Completion timestamp'), |
There was a problem hiding this comment.
completedAt is optional even when status is completed/failed/expired, which allows internally inconsistent training records (e.g., completed training with no completion timestamp). Consider adding an object-level refinement to require completedAt when the status implies the training attempt finished (and potentially require expiresAt when status is expired).
| status: SupplierAssessmentStatusSchema.describe('Assessment status'), | ||
|
|
||
| /** | ||
| * User or team who performed the assessment | ||
| */ |
There was a problem hiding this comment.
SupplierAssessmentStatusSchema includes pending/in_progress, but the assessment record schema requires fields that imply completion (e.g., assessedAt / validUntil). Consider either (a) splitting “assessment in progress” vs “completed assessment” into separate schemas, or (b) making completion/validity timestamps conditional via refinement based on status.
| assessedAt: z.number().describe('Assessment timestamp'), | ||
|
|
||
| /** | ||
| * Assessment validity expiry (Unix milliseconds) | ||
| */ | ||
| validUntil: z.number().describe('Assessment validity expiry timestamp'), |
There was a problem hiding this comment.
assessedAt/validUntil are required even when status is pending or in_progress, which makes it hard to represent an assessment that hasn’t completed yet. If you keep these statuses, consider making these fields optional and enforcing them only for terminal states (completed/expired/failed).
| assessedAt: z.number().describe('Assessment timestamp'), | |
| /** | |
| * Assessment validity expiry (Unix milliseconds) | |
| */ | |
| validUntil: z.number().describe('Assessment validity expiry timestamp'), | |
| assessedAt: z.number().optional().describe('Assessment timestamp'), | |
| /** | |
| * Assessment validity expiry (Unix milliseconds) | |
| */ | |
| validUntil: z.number().optional().describe('Assessment validity expiry timestamp'), |
| * Regulatory notification deadline in hours (e.g., GDPR 72h) | ||
| */ | ||
| regulatorDeadlineHours: z.number().optional() | ||
| .describe('Regulatory notification deadline in hours'), |
There was a problem hiding this comment.
notifyRegulators and regulatorDeadlineHours are logically dependent, but the schema currently allows notifyRegulators: true without a deadline (and allows a deadline when notifyRegulators is false). Consider adding an object-level refinement so regulatorDeadlineHours is required (and positive) when notifyRegulators is true.
| .describe('Regulatory notification deadline in hours'), | |
| .describe('Regulatory notification deadline in hours'), | |
| }).superRefine((value, ctx) => { | |
| if (value.notifyRegulators) { | |
| if (value.regulatorDeadlineHours == null) { | |
| ctx.addIssue({ | |
| code: z.ZodIssueCode.custom, | |
| path: ['regulatorDeadlineHours'], | |
| message: 'regulatorDeadlineHours is required when notifyRegulators is true', | |
| }); | |
| } else if (value.regulatorDeadlineHours <= 0) { | |
| ctx.addIssue({ | |
| code: z.ZodIssueCode.custom, | |
| path: ['regulatorDeadlineHours'], | |
| message: 'regulatorDeadlineHours must be a positive number when notifyRegulators is true', | |
| }); | |
| } | |
| } else if (value.regulatorDeadlineHours != null) { | |
| ctx.addIssue({ | |
| code: z.ZodIssueCode.custom, | |
| path: ['regulatorDeadlineHours'], | |
| message: 'regulatorDeadlineHours must be omitted when notifyRegulators is false', | |
| }); | |
| } |
| recertificationIntervalDays: z.number().default(365) | ||
| .describe('Default recertification interval in days'), |
There was a problem hiding this comment.
recertificationIntervalDays (and related plan intervals like gracePeriodDays / reminderDaysBefore) are currently unconstrained numbers, so negative or fractional values validate. Consider constraining these to non-negative/positive integers (e.g., .int().min(0|1)) to keep plan configs meaningful.
| /** | ||
| * Recurrence interval in months (0 = one-time) | ||
| */ | ||
| recurrenceMonths: z.number().default(0).describe('Recurrence interval in months (0 = one-time)'), |
There was a problem hiding this comment.
recurrenceMonths represents a recurrence interval ("0 = one-time") but is currently z.number() with no bounds, so negative or fractional values will validate. Consider constraining it to a non-negative integer (e.g., .int().min(0)) to prevent invalid schedules from being accepted.
| recurrenceMonths: z.number().default(0).describe('Recurrence interval in months (0 = one-time)'), | |
| recurrenceMonths: z.number().int().min(0).default(0).describe('Recurrence interval in months (0 = one-time)'), |
| /** | ||
| * Default escalation timeout in minutes before auto-escalation | ||
| */ | ||
| escalationTimeoutMinutes: z.number().default(30) |
There was a problem hiding this comment.
escalationTimeoutMinutes is a duration but currently allows negative / fractional values (z.number().default(30)). Consider adding bounds (e.g., .int().min(1) or .min(0) depending on whether 0 is meaningful) so invalid escalation policies can’t validate.
| escalationTimeoutMinutes: z.number().default(30) | |
| escalationTimeoutMinutes: z.number().int().min(1).default(30) |
Closes schema gaps identified in the ISO 27001:2022 compliance audit that block certification at the organizational control layer.
New schemas
system/incident-response.zod.ts(A.5.24–A.5.28) — Incident severity/category/status enums, NIST SP 800-61 response phases, notification matrix with escalation chains, org-level response policysystem/supplier-security.zod.ts(A.5.19–A.5.22) — Supplier risk levels, per-requirement compliance assessment, remediation tracking, reassessment policysystem/training.zod.ts(A.6.3) — Course definitions with validity/passing scores, completion records, org training plans with recertification intervalsExtended schemas
system/compliance.zod.ts(A.5.35) —AuditScheduleSchemafor recurring internal/external audits,AuditFindingSchemawith severity→remediation→verification lifecycle.ComplianceConfigSchemagainsauditSchedulesfield.system/change-management.zod.ts(A.8.32) —securityImpactoptional field onChangeRequestSchema: risk level, affected data classifications, security reviewer sign-off workflowsystem/security-context.zod.ts— ExtractedDataClassificationSchemaandComplianceFrameworkSchemaas canonical shared enums, eliminating inline duplication across all security subsystem schemasDeduplication with existing protocols
DataClassificationSchema(pii/phi/pci/financial/confidential/internal/public) — extracted fromsecurity-context.zod.tsas canonical source; all new schemas import instead of inlining. Also replaced 3 pre-existing inline copies withinsecurity-context.zod.tsitself.ComplianceFrameworkSchema(gdpr/hipaa/sox/pci_dss/ccpa/iso27001) — extracted fromsecurity-context.zod.ts; used by both existingComplianceAuditRequirementSchemaand newAuditFindingSchema/AuditScheduleSchema.incident-response(incident lifecycle management) ≠audit.zod.ts(automated event logging)AuditScheduleSchema(planned human audits) ≠AuditConfigSchema(automated audit trail config)AuditFindingSeveritySchema(critical/major/minor/observation) ≠AuditEventSeverity(syslog-style debug→emergency)IncidentNotificationRuleSchema(severity-based escalation with pagerduty) ≠NotificationConfigSchema(general delivery channels)Infrastructure
system/index.tsROADMAP.md— new Phase 6.5 section tracking ISO 27001 schema coverageNot in scope (tracked in roadmap)
string[]to structured enum (A.8.2)Original prompt
🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.