create-filegrc 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/package.json +2 -2
  2. package/src/cli.js +7 -1
  3. package/src/defaults.js +218 -11
  4. package/src/index.js +19 -7
  5. package/template/AGENTS.md +40 -9
  6. package/template/README.md +16 -8
  7. package/template/WORKSPACE.md +13 -0
  8. package/template/data/AGENTS.md +12 -4
  9. package/template/data/appointments/appointment-independent-policy-reviewer.json +11 -0
  10. package/template/data/collection-reviews/collection-review-complementary-control.json +10 -0
  11. package/template/data/collection-reviews/collection-review-framework.json +10 -0
  12. package/template/data/collection-reviews/collection-review-person.json +10 -0
  13. package/template/data/collection-reviews/collection-review-system.json +10 -0
  14. package/template/data/collection-reviews/collection-review-vendor.json +10 -0
  15. package/template/data/documents/document-business-continuity-disaster-recovery.json +3 -2
  16. package/template/data/documents/document-business-continuity-disaster-recovery.md +2 -0
  17. package/template/data/documents/document-contractor-policy-acknowledgement.json +3 -2
  18. package/template/data/documents/document-contractor-training-acknowledgement.json +3 -2
  19. package/template/data/documents/document-data-retention-schedule.json +3 -2
  20. package/template/data/documents/document-employee-handbook-acknowledgement.json +3 -2
  21. package/template/data/documents/document-employee-policy-acknowledgement.json +3 -2
  22. package/template/data/documents/document-employee-training-acknowledgement.json +3 -2
  23. package/template/data/documents/document-incident-response-plan.json +3 -2
  24. package/template/data/documents/document-incident-response-plan.md +2 -0
  25. package/template/data/documents/document-soc2-management-assertion.json +2 -1
  26. package/template/data/documents/document-soc2-management-representation.json +2 -1
  27. package/template/data/documents/document-soc2-period-completeness.json +2 -1
  28. package/template/data/documents/document-soc2-system-description.json +2 -1
  29. package/template/data/obligations/AGENTS.md +1 -1
  30. package/template/data/policies/policy-anti-bribery-corruption.json +3 -2
  31. package/template/data/policies/policy-clear-desk-screen.json +3 -2
  32. package/template/data/policies/policy-data-protection-handling.json +3 -2
  33. package/template/data/policies/policy-employee-handbook.json +3 -2
  34. package/template/data/policies/policy-information-security.json +3 -2
  35. package/template/data/policies/policy-information-security.md +1 -1
  36. package/template/data/policies/policy-mobile-computing-communications.json +3 -2
  37. package/template/data/renderer.json +1 -2
  38. package/template/data/systems/system-filegrc-program-repository.md +2 -2
  39. package/template/data/workspace.json +1 -1
  40. package/template/package.json +3 -2
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "create-filegrc",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
4
4
  "description": "Create a filegrc workspace for a SOC 2 program",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "git+https://github.com/Sunpeak-AI/filegrc.git"
8
+ "url": "git+https://github.com/Alignbase/filegrc.git"
9
9
  },
10
10
  "type": "module",
11
11
  "bin": {
package/src/cli.js CHANGED
@@ -68,6 +68,10 @@ export async function runCli(argv = process.argv.slice(2)) {
68
68
  console.log("");
69
69
  console.log(` cd ${shellQuote(result.target)}`);
70
70
  if (options.install === false) console.log(" npm install");
71
+ if (result.gitMode !== "existing-worktree") {
72
+ console.log(" git add .");
73
+ console.log(' git commit -m "Initialize FileGRC program"');
74
+ }
71
75
  if (!result.setup) console.log(" npx filegrc setup");
72
76
  if (result.setup) console.log(" npx filegrc program-path --next --json");
73
77
  console.log(" npm run validate");
@@ -84,7 +88,9 @@ export async function runCli(argv = process.argv.slice(2)) {
84
88
  ? ` 1. Confirm the selected assurance goal with management: ${assuranceGoalLabel(result.setup.target.assuranceGoal)}.`
85
89
  : " 1. Select and confirm the assurance goal.");
86
90
  console.log(" 2. Appoint an independent reviewer who is separate from the policy owner.");
87
- console.log("Review the generated records, then commit the approved baseline.");
91
+ console.log(result.gitMode === "existing-worktree"
92
+ ? "Review the generated records and commit only this workspace's approved baseline."
93
+ : "Connect the dedicated private origin and push main before using browser writes.");
88
94
  }
89
95
 
90
96
  function shellQuote(value) {
package/src/defaults.js CHANGED
@@ -14,6 +14,41 @@ const ROLE_TRAINING_IDS = [
14
14
  "training-privileged-sensitive-roles",
15
15
  "training-anti-bribery-high-risk-roles"
16
16
  ];
17
+ const FILEGRC_SOURCE_FAMILIES = [
18
+ "training-acknowledgement",
19
+ "exception-finding",
20
+ "governance",
21
+ "risk-management",
22
+ "vendor-management"
23
+ ];
24
+ const FILEGRC_SOURCE_CONTROL_CODES = new Set([
25
+ "GOV-01",
26
+ "GOV-02",
27
+ "GOV-03",
28
+ "HR-01",
29
+ "HR-02",
30
+ "RSK-01",
31
+ "MON-01",
32
+ "EXC-01",
33
+ "VEN-01",
34
+ "VEN-02"
35
+ ]);
36
+ const SOURCE_FAMILIES = [
37
+ ["workforce", "Workforce System"],
38
+ ["training-acknowledgement", "Training and Acknowledgements"],
39
+ ["identity-access", "Identity and Access Systems"],
40
+ ["production-change", "Production Change Systems"],
41
+ ["security-monitoring", "Security Monitoring Systems"],
42
+ ["vulnerability-management", "Vulnerability Management"],
43
+ ["endpoint-asset", "Endpoint Management Systems"],
44
+ ["backup-recovery", "Backup and Recovery"],
45
+ ["vendor-management", "Vendors"],
46
+ ["exception-finding", "Exceptions and Findings"],
47
+ ["data-handling", "Data Protection Configuration"],
48
+ ["network-security", "Network Security Systems"],
49
+ ["governance", "Governance"],
50
+ ["risk-management", "Risk Management"]
51
+ ];
17
52
 
18
53
  const commonCriteria = [
19
54
  ["CC1.1", "Integrity and ethical values", "Set, communicate, and enforce standards for integrity and ethical conduct."],
@@ -467,7 +502,11 @@ const obligations = [
467
502
  ownerIds: [POLICY_OWNER_APPOINTMENT_ID],
468
503
  scopeResourceIds: ["training-security-awareness"],
469
504
  templateResourceId: "training-security-awareness",
470
- controlIds: ["control-security-training"],
505
+ controlIds: [
506
+ "control-security-communication",
507
+ "control-workforce-expectations",
508
+ "control-security-training"
509
+ ],
471
510
  policyIds: [INFORMATION_SECURITY_POLICY_ID, DATA_POLICY_ID]
472
511
  },
473
512
  {
@@ -588,7 +627,7 @@ const obligations = [
588
627
  activityType: "vendor-review",
589
628
  recurrence: calendar("year", 1),
590
629
  ownerIds: [POLICY_OWNER_APPOINTMENT_ID],
591
- controlIds: ["control-vendor-monitoring"],
630
+ controlIds: ["control-vendor-due-diligence", "control-vendor-monitoring"],
592
631
  policyIds: [INFORMATION_SECURITY_POLICY_ID, DATA_POLICY_ID]
593
632
  },
594
633
  {
@@ -685,7 +724,8 @@ const obligations = [
685
724
  id: "obligation-high-risk-departure-access",
686
725
  title: "Revoke access at or before departure notice",
687
726
  activityType: "access-removal",
688
- recurrence: event("high-risk-person-ended"),
727
+ recurrence: event("person-ended"),
728
+ eventRiskLevels: ["high"],
689
729
  triggerPrompt: "Involuntary or high-risk departure?",
690
730
  window: eventWindowHours(0),
691
731
  ownerIds: [POLICY_OWNER_APPOINTMENT_ID],
@@ -857,7 +897,150 @@ const obligations = [
857
897
  triggerPrompt: "Material security incident?",
858
898
  window: eventWindow(7),
859
899
  ownerIds: [OVERSIGHT_TEAM_ID],
860
- controlIds: ["control-monitoring-remediation"],
900
+ controlIds: ["control-monitoring-remediation", "control-security-exceptions"],
901
+ policyIds: [INFORMATION_SECURITY_POLICY_ID]
902
+ },
903
+ {
904
+ id: "obligation-vendor-activation-review",
905
+ title: "Complete vendor activation review",
906
+ activityType: "vendor-review",
907
+ recurrence: event("vendor-activated"),
908
+ triggerPrompt: "Vendor activated?",
909
+ window: eventWindow(30),
910
+ ownerIds: [POLICY_OWNER_APPOINTMENT_ID],
911
+ controlIds: ["control-vendor-due-diligence", "control-vendor-monitoring"],
912
+ policyIds: [INFORMATION_SECURITY_POLICY_ID]
913
+ },
914
+ {
915
+ id: "obligation-vendor-termination-closeout",
916
+ title: "Revoke vendor access and confirm data return or disposal",
917
+ activityType: "access-removal",
918
+ recurrence: event("vendor-terminated"),
919
+ triggerPrompt: "Vendor terminated?",
920
+ window: eventWindow(7),
921
+ ownerIds: [POLICY_OWNER_APPOINTMENT_ID],
922
+ controlIds: ["control-vendor-monitoring", "control-access-review-offboarding"],
923
+ policyIds: [INFORMATION_SECURITY_POLICY_ID, DATA_POLICY_ID]
924
+ },
925
+ {
926
+ id: "obligation-data-use-change-assessment",
927
+ title: "Assess the changed data use and control impact",
928
+ activityType: "risk-assessment",
929
+ recurrence: event("material-data-use-change"),
930
+ triggerPrompt: "Material data-use change?",
931
+ window: eventWindow(30),
932
+ ownerIds: [OVERSIGHT_TEAM_ID],
933
+ controlIds: ["control-risk-assessment", "control-data-classification-inventory"],
934
+ policyIds: [INFORMATION_SECURITY_POLICY_ID, DATA_POLICY_ID]
935
+ },
936
+ {
937
+ id: "obligation-incident-closure-review",
938
+ title: "Complete incident closure and lessons-learned review",
939
+ activityType: "incident-retrospective",
940
+ recurrence: event("incident-closed"),
941
+ triggerPrompt: "Incident closed?",
942
+ window: eventWindow(7),
943
+ ownerIds: [OVERSIGHT_TEAM_ID],
944
+ controlIds: ["control-incident-response", "control-monitoring-remediation"],
945
+ policyIds: [INFORMATION_SECURITY_POLICY_ID]
946
+ },
947
+ {
948
+ id: "obligation-policy-revision-approval",
949
+ title: "Review and approve the revised policy",
950
+ activityType: "policy-review",
951
+ recurrence: event("policy-revised"),
952
+ triggerPrompt: "Policy materially revised?",
953
+ window: eventWindow(30),
954
+ ownerIds: [OVERSIGHT_TEAM_ID],
955
+ controlIds: ["control-policy-management"],
956
+ policyIds: [INFORMATION_SECURITY_POLICY_ID]
957
+ },
958
+ {
959
+ id: "obligation-emergency-change-review",
960
+ title: "Complete emergency-change post-review",
961
+ activityType: "change-review",
962
+ recurrence: event("emergency-change"),
963
+ triggerPrompt: "Emergency change completed?",
964
+ window: eventWindow(2),
965
+ ownerIds: [OVERSIGHT_TEAM_ID],
966
+ controlIds: ["control-change-management"],
967
+ policyIds: [INFORMATION_SECURITY_POLICY_ID]
968
+ },
969
+ {
970
+ id: "obligation-exception-expiry-review",
971
+ title: "Review expired exception and compensating controls",
972
+ activityType: "exception-review",
973
+ recurrence: event("exception-expired"),
974
+ triggerPrompt: "Exception expired?",
975
+ window: eventWindow(1),
976
+ ownerIds: [POLICY_OWNER_APPOINTMENT_ID],
977
+ controlIds: ["control-monitoring-remediation", "control-security-exceptions"],
978
+ policyIds: [INFORMATION_SECURITY_POLICY_ID]
979
+ },
980
+ {
981
+ id: "obligation-service-account-creation-review",
982
+ title: "Authorize and review the new service account",
983
+ activityType: "access-provisioning",
984
+ recurrence: event("service-account-created"),
985
+ triggerPrompt: "Service account created?",
986
+ window: eventWindow(3),
987
+ ownerIds: [POLICY_OWNER_APPOINTMENT_ID],
988
+ controlIds: ["control-access-authorization"],
989
+ policyIds: [INFORMATION_SECURITY_POLICY_ID]
990
+ },
991
+ {
992
+ id: "obligation-service-account-expiry",
993
+ title: "Disable or renew the expired service account",
994
+ activityType: "access-removal",
995
+ recurrence: event("service-account-expired"),
996
+ triggerPrompt: "Service account expired?",
997
+ window: eventWindow(1),
998
+ ownerIds: [POLICY_OWNER_APPOINTMENT_ID],
999
+ controlIds: ["control-access-review-offboarding"],
1000
+ policyIds: [INFORMATION_SECURITY_POLICY_ID]
1001
+ },
1002
+ {
1003
+ id: "obligation-vulnerability-confirmed-remediation",
1004
+ title: "Assign confirmed vulnerability remediation",
1005
+ activityType: "remediation",
1006
+ recurrence: event("vulnerability-confirmed"),
1007
+ triggerPrompt: "Vulnerability confirmed?",
1008
+ window: eventWindow(3),
1009
+ ownerIds: [POLICY_OWNER_APPOINTMENT_ID],
1010
+ controlIds: ["control-vulnerability-management"],
1011
+ policyIds: [INFORMATION_SECURITY_POLICY_ID]
1012
+ },
1013
+ {
1014
+ id: "obligation-vulnerability-overdue-escalation",
1015
+ title: "Escalate overdue vulnerability remediation",
1016
+ activityType: "remediation",
1017
+ recurrence: event("vulnerability-overdue"),
1018
+ triggerPrompt: "Vulnerability remediation overdue?",
1019
+ window: eventWindow(1),
1020
+ ownerIds: [OVERSIGHT_TEAM_ID],
1021
+ controlIds: ["control-vulnerability-management", "control-monitoring-remediation"],
1022
+ policyIds: [INFORMATION_SECURITY_POLICY_ID]
1023
+ },
1024
+ {
1025
+ id: "obligation-asset-disposal-proof",
1026
+ title: "Record asset sanitization and disposal proof",
1027
+ activityType: "asset-recovery",
1028
+ recurrence: event("asset-disposed"),
1029
+ triggerPrompt: "Asset disposed?",
1030
+ window: eventWindow(7),
1031
+ ownerIds: [POLICY_OWNER_APPOINTMENT_ID],
1032
+ controlIds: ["control-inventory-configuration", "control-data-retention-disposal"],
1033
+ policyIds: [INFORMATION_SECURITY_POLICY_ID, DATA_POLICY_ID]
1034
+ },
1035
+ {
1036
+ id: "obligation-continuity-activation-review",
1037
+ title: "Review continuity activation, recovery, and follow-up",
1038
+ activityType: "continuity-review",
1039
+ recurrence: event("continuity-activated"),
1040
+ triggerPrompt: "Continuity plan activated?",
1041
+ window: eventWindow(7),
1042
+ ownerIds: [OVERSIGHT_TEAM_ID],
1043
+ controlIds: ["control-continuity-exercise", "control-monitoring-remediation"],
861
1044
  policyIds: [INFORMATION_SECURITY_POLICY_ID]
862
1045
  }
863
1046
  ];
@@ -899,9 +1082,9 @@ export function baselineRecordFiles(effectiveDate, starter = "security") {
899
1082
  title: `${reference}: ${name}`,
900
1083
  frameworkId: FRAMEWORK_ID,
901
1084
  reference,
902
- applicability: "applicable",
1085
+ applicability: "undetermined",
903
1086
  description,
904
- applicabilityRationale: "Included in the default SOC 2 Security baseline. Confirm applicability and exact interpretation with the selected auditor.",
1087
+ applicabilityRationale: "Confirm applicability against the selected service, scope, and auditor guidance before accepting this starter criterion.",
905
1088
  tags: ["security", "common-criteria"]
906
1089
  }));
907
1090
  const descriptionRequirements = descriptionCriteria.map(([reference, name, description]) => ({
@@ -910,9 +1093,9 @@ export function baselineRecordFiles(effectiveDate, starter = "security") {
910
1093
  title: `${reference}: ${name}`,
911
1094
  frameworkId: DESCRIPTION_FRAMEWORK_ID,
912
1095
  reference,
913
- applicability: "applicable",
1096
+ applicability: "undetermined",
914
1097
  description,
915
- applicabilityRationale: "Included for preparing the system description. Confirm the official criterion and expected presentation with the selected auditor.",
1098
+ applicabilityRationale: "Confirm applicability against the selected service and auditor guidance before accepting this starter description criterion.",
916
1099
  tags: ["description-criteria"]
917
1100
  }));
918
1101
  const controlRecords = controls.map((control) => ({
@@ -928,7 +1111,10 @@ export function baselineRecordFiles(effectiveDate, starter = "security") {
928
1111
  controlType: control.controlType,
929
1112
  operationMode: control.operationMode,
930
1113
  operationPattern: control.operationPattern,
931
- policyIds: control.policies
1114
+ policyIds: control.policies,
1115
+ ...(FILEGRC_SOURCE_CONTROL_CODES.has(control.code)
1116
+ ? { evidenceSourceIds: ["system-filegrc-program-repository"] }
1117
+ : {})
932
1118
  }));
933
1119
  const team = {
934
1120
  id: OVERSIGHT_TEAM_ID,
@@ -951,14 +1137,14 @@ export function baselineRecordFiles(effectiveDate, starter = "security") {
951
1137
  environment: "Git repository",
952
1138
  classificationId: "confidential",
953
1139
  internetExposed: false,
954
- evidenceSourceKinds: ["training-acknowledgement", "exception-finding"],
1140
+ evidenceSourceKinds: FILEGRC_SOURCE_FAMILIES,
955
1141
  evidenceOwnerIds: [POLICY_OWNER_APPOINTMENT_ID]
956
1142
  };
957
1143
  const obligationRecords = obligations.map((obligation) => ({
958
1144
  id: obligation.id,
959
1145
  type: "obligation",
960
1146
  title: obligation.title,
961
- status: "active",
1147
+ status: "proposed",
962
1148
  activityType: obligation.activityType,
963
1149
  recurrence: obligation.recurrence.mode === "calendar"
964
1150
  ? { ...obligation.recurrence, anchorDate: effectiveDate }
@@ -966,12 +1152,32 @@ export function baselineRecordFiles(effectiveDate, starter = "security") {
966
1152
  ownerIds: obligation.ownerIds,
967
1153
  startsOn: effectiveDate,
968
1154
  ...(obligation.triggerPrompt ? { triggerPrompt: obligation.triggerPrompt } : {}),
1155
+ ...(obligation.eventRiskLevels ? { eventRiskLevels: obligation.eventRiskLevels } : {}),
969
1156
  ...(obligation.window ? { window: obligation.window } : {}),
970
1157
  ...(obligation.scopeResourceIds ? { scopeResourceIds: obligation.scopeResourceIds } : {}),
971
1158
  ...(obligation.templateResourceId ? { templateResourceId: obligation.templateResourceId } : {}),
972
1159
  controlIds: obligation.controlIds,
973
1160
  policyIds: obligation.policyIds
974
1161
  }));
1162
+ const sourceCoverageRecords = SOURCE_FAMILIES.map(([sourceFamilyId, title]) => {
1163
+ const filegrcManaged = FILEGRC_SOURCE_FAMILIES.includes(sourceFamilyId);
1164
+ return {
1165
+ id: `source-coverage-${sourceFamilyId}`,
1166
+ type: "source-coverage",
1167
+ title: `${title} coverage`,
1168
+ status: filegrcManaged ? "active" : "planned",
1169
+ sourceFamilyId,
1170
+ coverageKind: filegrcManaged ? "filegrc" : "external-system",
1171
+ scopeResourceIds: ["workspace"],
1172
+ ownerIds: [POLICY_OWNER_APPOINTMENT_ID],
1173
+ ...(filegrcManaged ? {
1174
+ collectionCadence: "Record work when it occurs and export the complete population for the audit period.",
1175
+ retention: "Keep records for the period defined in the approved Data Retention Schedule.",
1176
+ reconciliationMethod: "Export the complete filegrc source-family population, compare it with related in-scope records and Work Queue activity, and investigate omissions or duplicates.",
1177
+ validFrom: effectiveDate
1178
+ } : {})
1179
+ };
1180
+ });
975
1181
 
976
1182
  const foundation = [
977
1183
  recordFile("systems", programRepository),
@@ -986,6 +1192,7 @@ export function baselineRecordFiles(effectiveDate, starter = "security") {
986
1192
  ...descriptionRequirements.map((record) => recordFile("requirements", record)),
987
1193
  ...controlRecords.map((record) => recordFile("controls", record)),
988
1194
  ...foundation,
1195
+ ...sourceCoverageRecords.map((record) => recordFile("source-coverage", record)),
989
1196
  ...obligationRecords.map((record) => recordFile("obligations", record))
990
1197
  ];
991
1198
  }
package/src/index.js CHANGED
@@ -10,7 +10,7 @@ const execute = promisify(execFile);
10
10
  const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
11
11
  const textExtensions = new Set(["", ".json", ".md", ".txt", ".yml", ".yaml", ".gitignore"]);
12
12
  const STARTER_PROFILES = new Set(["foundation", "security"]);
13
- const SECURITY_TEMPLATE_COLLECTIONS = new Set(["documents", "policies", "training"]);
13
+ const SECURITY_TEMPLATE_COLLECTIONS = new Set(["collection-reviews", "documents", "policies", "training"]);
14
14
 
15
15
  export async function createFilegrc(options = {}) {
16
16
  const parameterConfig = JSON.parse(await readFile(join(packageRoot, "template-parameters.json"), "utf8"));
@@ -29,7 +29,7 @@ export async function createFilegrc(options = {}) {
29
29
  const starterText = starterTemplateText(starter, prompted.company_name);
30
30
  const values = {
31
31
  ...prompted,
32
- effective_date: options.effectiveDate ?? new Date().toISOString().slice(0, 10),
32
+ effective_date: options.effectiveDate ?? calendarDateInTimezone(prompted.timezone),
33
33
  project_name: normalizePackageName(basename(target)),
34
34
  filegrc_version: engine.version,
35
35
  filegrc_version_range: engine.dependency,
@@ -74,6 +74,16 @@ export async function createFilegrc(options = {}) {
74
74
  };
75
75
  }
76
76
 
77
+ function calendarDateInTimezone(timezone, date = new Date()) {
78
+ const values = Object.fromEntries(new Intl.DateTimeFormat("en-US", {
79
+ timeZone: timezone,
80
+ year: "numeric",
81
+ month: "2-digit",
82
+ day: "2-digit"
83
+ }).formatToParts(date).map(({ type, value }) => [type, value]));
84
+ return `${values.year}-${values.month}-${values.day}`;
85
+ }
86
+
77
87
  export function normalizeStarterProfile(value = "security") {
78
88
  const profile = String(value || "security").trim().toLowerCase();
79
89
  const normalized = profile === "empty" ? "foundation" : profile === "soc2-security" ? "security" : profile;
@@ -396,7 +406,7 @@ async function applyStarterScope(target, starter, effectiveDate) {
396
406
  }
397
407
 
398
408
  function starterStages(starter, counts) {
399
- const foundationTypes = new Set(["workspace", "renderer-settings", "person", "team", "system"]);
409
+ const foundationTypes = new Set(["workspace", "renderer-settings", "person", "appointment", "team", "system"]);
400
410
  const foundation = Object.entries(counts.byType)
401
411
  .filter(([type]) => foundationTypes.has(type))
402
412
  .reduce((total, [, count]) => total + count, 0);
@@ -420,10 +430,11 @@ function starterTemplateText(starter, companyName) {
420
430
  agent_purpose: `This repository is ${companyName}’s foundation filegrc workspace. Engineers and agents maintain the source records under \`data/\`. The \`filegrc\` package validates, searches, edits, and renders those files. No framework or assurance program has been selected yet.`,
421
431
  starter_baseline: `## Foundation baseline
422
432
 
423
- The generated workspace starts with five structural records:
433
+ The generated workspace starts with foundational program records:
424
434
 
425
435
  - Workspace and renderer settings
426
436
  - The initial active owner
437
+ - The two core Appointment records: an active Policy Owner plus a planned Independent Policy Reviewer assignment. Create another Appointment only when management actually delegates a named responsibility.
427
438
  - A planned security and risk oversight team that still needs an independent chair
428
439
  - The filegrc Git repository as a governance system of record
429
440
  - A default 5x5 risk method and Public, Internal, Confidential, and Restricted data classifications
@@ -432,7 +443,7 @@ This profile does not include framework requirements, policies, governed documen
432
443
  audit_preparation_guidance: "The foundation profile does not include the local SOC 2 management-document templates used by `prepare-audit`. Add reviewed templates and program scope before initializing audit work. Audit preparation must not invent missing policy, control, or evidence facts.",
433
444
  starter_setup: `## Start the program
434
445
 
435
- This foundation profile contains the workspace, initial owner, oversight team, renderer settings, and filegrc system of record. It does not select a framework or create proposed policies, controls, obligations, or evidence.
446
+ This foundation profile contains the workspace, initial owner, core Appointments, oversight team, renderer settings, and filegrc system of record. It does not select a framework or create proposed policies, controls, obligations, or evidence.
436
447
 
437
448
  1. Run \`npx filegrc setup\` for guided service and goal setup, or use browser onboarding.
438
449
  2. Use \`npx filegrc guide --json\` before creating framework requirements, policies, controls, obligations, and evidence sources.
@@ -453,6 +464,7 @@ The generated workspace starts with the SOC 2 Security category:
453
464
  - The 33 Common Criteria reference IDs from CC1.1 through CC9.2, without the licensed criteria text
454
465
  - The nine Description Criteria reference IDs from DC1 through DC9, without the licensed criteria text
455
466
  - Planned controls mapped to those references and the included policies
467
+ - The two core Appointment records. Policy Owner starts active; Independent Policy Reviewer remains Ready until assigned. Program coordination, incident, recovery, executive, legal, privacy, insurance, communications, and audit-coordination functions stay with the Policy Owner unless management delegates one through a custom Appointment.
456
468
  - A security and risk oversight team chaired by an independent reviewer who may be internal or external
457
469
  - Recurring obligations for the reviews, scans, tests, training, and meetings required by the included policies
458
470
  - A default 5x5 risk method and Public, Internal, Confidential, and Restricted data classifications
@@ -504,13 +516,13 @@ async function runCombinedSetup(target, input) {
504
516
  async function writeMinimalLockfile(target, name, versionRange) {
505
517
  const lock = {
506
518
  name,
507
- version: "0.4.0",
519
+ version: "0.5.1",
508
520
  lockfileVersion: 3,
509
521
  requires: true,
510
522
  packages: {
511
523
  "": {
512
524
  name,
513
- version: "0.4.0",
525
+ version: "0.5.1",
514
526
  dependencies: { filegrc: versionRange }
515
527
  }
516
528
  }
@@ -18,7 +18,7 @@ npx filegrc list person --json
18
18
  npx filegrc program-readiness --summary --json
19
19
  ```
20
20
 
21
- `program-path --next --json` gives agents the current step and first action. Use `--summary` for all five step statuses or `--current` for the current step’s full renderer Instructions, Use, Policy Basis, commands, and next actions. The general guide lists every supported action and record type. A type guide repeats that page guidance and adds timing, required and conditional fields, current relationship candidates, JSON location, and Markdown slots.
21
+ `program-path --next --json` gives agents the current step and first action. Use `--summary` for all five step statuses or `--current` for the current step’s page summaries, detailed guidance fields, commands, and next actions. The general guide lists every supported action and record type. A type guide adds the checks needed for that resource, including timing, required and conditional fields, current relationship candidates, JSON location, and Markdown slots.
22
22
 
23
23
  For a new record, generate a mutation envelope:
24
24
 
@@ -52,6 +52,20 @@ Read `data/AGENTS.md` before changing records. More specific instructions inside
52
52
  - Do not store secrets, credentials, session data, or personal data that may need to be erased from Git history.
53
53
  - Keep the editable local server on loopback or behind trusted authentication. Use the read-only static build for audit sharing.
54
54
 
55
+ ## Source truth and derived workflow
56
+
57
+ The JSON and Markdown under `data/`, the installed model, policy content, and Git history are the inputs to FileGRC’s shared workflow calculation. Source files hold facts, decisions, relationships, dates, status, and evidence references. They do not each need a copy of the generic audit-readiness instructions or calculated TODO list.
58
+
59
+ Use `npx filegrc workflow --json` for the complete derived checklist, named readiness assessments, blockers, Work Items, and recommended next action. `guide`, `list --workflow`, `get --workflow`, mutation previews, the HTTP API, and the browser consume the same calculation. Resolve a derived finding by changing its source facts, recording a reviewed applicability decision, accepting an allowed Exception, or completing authoritative assigned work. Never add a separate TODO file or UI-only completion flag for calculated work.
60
+
61
+ FileGRC marks an item `blocked` only when named prerequisite records must be resolved first. A missing record, editable error, or management decision is `ready` when you can act on it now, even when it prevents a readiness assessment from passing.
62
+
63
+ An Action Item or Audit Request is a source record because it captures a real assignment, owner, deadline, and completion proof. A Collection Review is also a source record because FileGRC cannot infer that management reviewed an apparently complete or empty collection. `npx filegrc guide RESOURCE_TYPE --json` returns the type-specific review criteria and current confirmation state. Use `npx filegrc review-collection RESOURCE_TYPE --scaffold`, fill the conclusion and reviewer facts, preview it, then apply it with `--yes`. FileGRC calculates the collection revision and marks the confirmation stale after a reviewed record or material scope fact changes.
64
+
65
+ Other prompts and blockers remain derived. After a direct file edit, run `npm run validate`, `npx filegrc reconcile --preview --json`, and `npx filegrc workflow --json`. Reconciliation reports source transitions that may need a dated Policy Event and linked tasks. It never treats a file diff as proof that a real-world event happened. Apply a candidate only after confirming the event facts. The result must match an equivalent browser or CLI edit.
66
+
67
+ Run `npm run check:milestone` in CI. Before an assurance goal is selected it checks structural validity. It checks Evidence Readiness after a goal is selected, then Period Health after candidate coverage dates exist.
68
+
55
69
  ## Git is the audit trail
56
70
 
57
71
  Git supplies file authors, commit timestamps, messages, diffs, and revisions. Do not add fields such as `createdAt`, `updatedAt`, `createdBy`, `updatedBy`, or a second change log.
@@ -86,10 +100,12 @@ Do not rewrite or remove committed records that explain prior audit periods. Clo
86
100
  If the installed CLI reports that this workspace uses an unsupported model, start with:
87
101
 
88
102
  ```sh
89
- npx filegrc migrate --to-model 2 --preview --json
103
+ npx filegrc migrate --to-model 3 --preview --json
90
104
  ```
91
105
 
92
- Resolve every missing value, conflict, and manual action in the preview before applying the migration with the same options and `--yes`.
106
+ Model v1 workspaces migrate to v2 first. Review the v3 preview’s automatic, review-required, and unsupported classifications before applying it with the same options and `--yes`. The migration creates no approvals, holders, evidence, or historical dates.
107
+
108
+ The [model v3 upgrade guide](https://github.com/Alignbase/filegrc/blob/main/docs/upgrading-to-model-v3.md) explains the classifications, automatic changes, and required post-migration review.
93
109
 
94
110
  Run these commands when working with records:
95
111
 
@@ -118,12 +134,14 @@ Headless agents get the same protection by exporting an edit payload with `fileg
118
134
 
119
135
  `data/renderer.json` stores committed renderer and repository preferences. New workspaces set `showOnboarding` to `true`, `repositoryMode` to `trunk`, `authoritativeBranch` to `main`, and `repositoryRemote` to `origin`. In trunk mode, completing or skipping onboarding commits the related change and starts its background push.
120
136
 
121
- Onboarding explains the file and Git workflow, the program path, policy obligations, and Policy Events before covering report types and the final audit stage. It then collects the initial service boundary, owner, business criticality, highest data classification, internet exposure, and optional program goal. It creates or updates one `system` record and stores that selected system and the management goal on `workspace`. It does not select framework records, link controls to the service, or create evidence. Selecting Type 1 or Type 2 does not create an audit engagement. Completing onboarding opens the Step 1 overview so the user can add the real reviewers and operators, finish the oversight team, and confirm the criteria, commitments, vendors, and systems before approving policies.
137
+ Onboarding explains the file and Git workflow, the program path, policy obligations, and Policy Events before covering report types and the final audit stage. It then collects the initial service boundary, owner, business criticality, highest data classification, internet exposure, and optional program goal. It creates or updates one `system` record, stores that selected system and the management goal on `workspace`, and creates one planned service-commitment prompt. Replace that prompt with the actual customer promise or approved service requirement before activation. Onboarding does not link controls to the service or create evidence. Selecting Type 1 or Type 2 does not create an audit engagement. Completing onboarding opens the Step 1 overview so the user can add the real reviewers and operators, finish the oversight team, and confirm the criteria, commitments, vendors, and systems before approving policies.
122
138
 
123
139
  The renderer is optional. Agents may set `showOnboarding` to `false` and maintain all records headlessly. Restart onboarding from Repository when useful. Read-only builds never run it.
124
140
 
125
141
  {{starter_baseline}}
126
142
 
143
+ Review all criteria against the actual service boundary in one explicit batch. Run `npx filegrc review-applicability --scaffold --type requirement > decisions.json`, fill every decision, then preview with `npx filegrc review-applicability decisions.json --preview --json` and apply the same file with `--yes`. Every decision needs a reviewer, date, and rationale. FileGRC records the current scope revision automatically.
144
+
127
145
  ## Work Queue and Policy Events
128
146
 
129
147
  Run the same obligation planner used by the web app:
@@ -138,10 +156,12 @@ Work Queue includes recurring obligations, Policy Event tasks, and every other o
138
156
  A calendar obligation’s recurrence anchor starts its first allowed cycle. Unless `window` narrows that range, completion is allowed from the cycle start through the day before the next cycle, and the item becomes overdue on the next cycle’s first day. Use **Record work** in Work Queue, or create and link a completion atomically with:
139
157
 
140
158
  ```sh
141
- npx filegrc complete obligation-id completion-record.json --expected-revision REVISION
159
+ npx filegrc complete obligation-id --scaffold --window-start YYYY-MM-DD --completed-on YYYY-MM-DD > completion-record.json
160
+ # Fill the actual work, evidence, review, and any null or empty required values.
161
+ npx filegrc complete obligation-id completion-record.json
142
162
  ```
143
163
 
144
- Keep prior completion links because the planner matches each dated record to its own period.
164
+ The scaffold includes the current obligation revision, so the second command rejects a stale Work Queue write. Keep prior completion links because the planner matches each dated record to its own period.
145
165
 
146
166
  Event obligations are templates. Do not mark a template complete or replace it for each occurrence. Use Trigger Work on Step 4 or run:
147
167
 
@@ -155,11 +175,13 @@ Run `npx filegrc obligations` first to preview every task, owner, deadline, and
155
175
  Complete an event action and link its new proof in one validated write:
156
176
 
157
177
  ```sh
158
- npx filegrc complete-action action-item-id completion-record.json --completed-on 2026-07-25 --expected-revision REVISION
178
+ npx filegrc complete-action action-item-id --scaffold --completed-on 2026-07-25 > completion-record.json
179
+ # Fill the actual work, evidence, review, and any null or empty required values.
180
+ npx filegrc complete-action action-item-id completion-record.json --completed-on 2026-07-25
159
181
  npx filegrc complete-event obligation-event-id --completed-on 2026-07-25 --expected-revision REVISION
160
182
  ```
161
183
 
162
- Read `REVISION` from `npx filegrc get RESOURCE_ID --mutation`. filegrc rejects a completion resource whose type does not match the obligation. It will close the event only after every action has its requested proof.
184
+ Completion scaffolds include the target revision. For other updates, read `REVISION` from `npx filegrc get RESOURCE_ID --mutation`. filegrc rejects a completion resource whose type does not match the obligation. It will close the event only after every action has its requested proof.
163
185
 
164
186
  ## Headless Markdown
165
187
 
@@ -241,7 +263,16 @@ Link a control test to its `audit-population` record when sampling applies. Link
241
263
 
242
264
  The initial program lead is {{policy_owner_name}}, {{policy_owner_job_title}}, at {{policy_owner_email}}. The separate Policy Owner Appointment records this person’s starting program authority, and the security reporting address is {{security_contact_email}}. Update the Person when their organizational position changes. End and replace Appointments when named authority moves to someone else.
243
265
 
244
- Appoint an independent management reviewer during policy review, not as a condition of defining the service boundary. The reviewer must be separate from the policy owner and able to challenge the owner’s decisions. Most organizations assign another internal leader or manager. An external reviewer is also allowed, and a one-person company needs one because no second internal person is available. The reviewer chairs Security and Risk Oversight and approves policies and governed documents.
266
+ Appoint an independent management reviewer during policy review, not as a condition of defining the service boundary. The reviewer must be separate from the policy owner and able to challenge the owner’s decisions. Assign another internal leader or manager when a suitable reviewer is available. Otherwise, appoint a qualified external reviewer. The reviewer chairs Security and Risk Oversight and approves policies and governed documents.
267
+
268
+ To appoint an internal reviewer, create or update that Person and set the planned Independent Policy Reviewer Appointment’s `holderId`, scope, start date, responsibilities, and independence rationale before making it active. When no suitable internal reviewer is available, include the reviewer’s real organizational job title, organization, start date, and independence rationale in `reviewer.json`, then preview the external-reviewer bundle before applying it:
269
+
270
+ ```sh
271
+ npx filegrc external-reviewer-setup --scaffold > reviewer.json
272
+ # Replace the null values with the reviewer's current facts and independence rationale.
273
+ npx filegrc external-reviewer-setup reviewer.json --preview --json
274
+ npx filegrc external-reviewer-setup reviewer.json --yes --json
275
+ ```
245
276
 
246
277
  The management reviewer and CPA auditor are different roles. Do not assign the CPA firm management or approval work without first confirming the firm's independence requirements.
247
278
 
@@ -19,7 +19,7 @@ npm run serve
19
19
 
20
20
  Requires Node.js 20 or newer and Git.
21
21
 
22
- Existing model v1 workspaces must run `npx filegrc migrate --to-model 2 --preview --json` after installing a model v2 package. Resolve every reported item before applying the same migration with `--yes`.
22
+ Existing model v2 workspaces must run `npx filegrc migrate --to-model 3 --preview --json` after installing a model v3 package. Review each automatic, review-required, and unsupported item before applying the same migration with `--yes`. Model v1 workspaces migrate to v2 first. See the [model v3 upgrade guide](https://github.com/Alignbase/filegrc/blob/main/docs/upgrading-to-model-v3.md).
23
23
 
24
24
  ## How it works
25
25
 
@@ -39,11 +39,11 @@ Detached and feature-branch checkouts are read-only in the browser by default. D
39
39
 
40
40
  ![filegrc SOC 2 program overview](docs/filegrc-home.png)
41
41
 
42
- 1. **Define scope.** Confirm people, dated appointments, teams, criteria, commitments, vendors, and in-scope systems. For Systems that produce evidence, add their source roles, access owners, and retrieval instructions.
43
- 2. **Approve policies.** Tailor the proposals and record separate owners and reviewers.
44
- 3. **Implement controls.** Add the real procedure, scope, operation pattern, and authoritative evidence Systems. Put calendar and event schedules in Obligations. Confirm every source is active and has the required role, access owners, and repeatable retrieval instructions before marking the Control implemented.
45
- 4. **Operate the program.** Work the queue, trigger Policy Events, maintain risks, and preserve dated evidence.
46
- 5. **Audit.** Record the CPA engagement and agreed period, support fieldwork, and build the packet.
42
+ 1. **Define scope.** Set program ownership, choose the criteria, and define the service, Systems, and providers in scope.
43
+ 2. **Approve policies.** Turn the starter policy set into approved rules that match how the organization works.
44
+ 3. **Implement controls.** Define how each control works, where its evidence comes from, and whether customers or providers have responsibilities.
45
+ 4. **Operate the program.** Run scheduled and event-driven work, maintain risk, and retain dated evidence.
46
+ 5. **Audit.** Set up the CPA engagement, support fieldwork, and prepare the evidence packet.
47
47
 
48
48
  Control implementation includes evidence-source readiness. Use `npx filegrc program-readiness --json` to find incomplete Control or System records. `npx filegrc evidence-map --json` remains available as a focused diagnostic. Create External Evidence during Step 4 only when a real export, report, screenshot, signed file, or approved external reference exists.
49
49
 
@@ -51,9 +51,10 @@ The Program Overview shows what is done, what is blocked, and what to do next.
51
51
 
52
52
  ## The routine work stays connected
53
53
 
54
- - **Work Queue** turns policy schedules and follow-up into upcoming, due, and overdue work.
54
+ - **Work Queue** turns policy schedules and follow-up into upcoming, blocked, due, and overdue work, with named blockers when a task cannot proceed.
55
55
  - **Policy Events** create the right tasks for hiring, departures, incidents, vendor changes, and other events.
56
56
  - **Program Readiness** checks whether management can begin a reliable evidence period.
57
+ - **Period Health** checks role, policy, control, source, obligation, and Git-history continuity across candidate and formal Type 2 dates.
57
58
  - **Audit Readiness** checks the engagement, period, documents, evidence, and Type 2 populations.
58
59
  - **Evidence packets** collect the scoped records, attachments, history, indexes, and checksums for delivery.
59
60
 
@@ -67,11 +68,18 @@ The browser is helpful, but it is not required. An agent can discover the model,
67
68
 
68
69
  ```sh
69
70
  npx filegrc program-path --next --json
71
+ npx filegrc workflow --json
72
+ npx filegrc reconcile --preview --json
73
+ npx filegrc period-health --require-healthy --json
74
+ npx filegrc review-applicability decisions.json --preview --json
75
+ npx filegrc review-collection person --scaffold
70
76
  npx filegrc guide risk-assessment --json
71
77
  npx filegrc obligations --json
78
+ npx filegrc complete OBLIGATION_ID --scaffold --window-start YYYY-MM-DD --completed-on YYYY-MM-DD
72
79
  npx filegrc program-readiness --summary --json
73
80
  npx filegrc audit-readiness audit-id --json
74
81
  npx filegrc evidence-packet --audit audit-id
82
+ npm run check:milestone
75
83
  ```
76
84
 
77
85
  Read `AGENTS.md` and `data/AGENTS.md` inside a generated workspace for the full headless workflow.
@@ -84,4 +92,4 @@ The independent CPA firm still selects samples, tests controls, evaluates except
84
92
 
85
93
  Do not put secrets or personal data that may need erasure into Git. The editable local server has no authentication and binds to loopback by default.
86
94
 
87
- Learn more at [filegrc.com](https://filegrc.com) or [view the source on GitHub](https://github.com/Sunpeak-AI/filegrc).
95
+ Learn more at [filegrc.com](https://filegrc.com) or [view the source on GitHub](https://github.com/Alignbase/filegrc).
@@ -27,6 +27,19 @@ npx filegrc validate --json
27
27
 
28
28
  Read `AGENTS.md` and `data/AGENTS.md` before broad changes.
29
29
 
30
+ ## Establish the Git baseline
31
+
32
+ Review the generated proposals and make an initial commit before recording setup decisions. This gives later changes a clear baseline and prevents first-run files from looking like real-world policy events.
33
+
34
+ If this is a dedicated repository:
35
+
36
+ ```sh
37
+ git add .
38
+ git commit -m "Initialize FileGRC program"
39
+ ```
40
+
41
+ The editable browser uses `main` and pushes saved changes to `origin`. Connect this repository to a dedicated private remote and push `main` before using browser writes. CLI and file-based users can manage Git on their normal review cadence, but should still commit the baseline before changing program facts.
42
+
30
43
  {{starter_setup}}
31
44
 
32
45
  filegrc manages GRC records and audit evidence. It does not replace infrastructure logging, monitoring, identity, backup, endpoint, or incident-detection systems.
@@ -8,6 +8,8 @@ Treat the installed model as the authority. Do not infer a schema from a nearby
8
8
 
9
9
  ```sh
10
10
  npx filegrc guide --json
11
+ npx filegrc workflow --json
12
+ npx filegrc reconcile --preview --json
11
13
  npx filegrc program-path --next --json
12
14
  npx filegrc types --json
13
15
  npx filegrc guide RESOURCE_TYPE --json
@@ -15,7 +17,9 @@ npx filegrc list RESOURCE_TYPE --json
15
17
  npx filegrc search "TERM" --json
16
18
  ```
17
19
 
18
- Use `program-path --next --json` to find the current lifecycle step and first action. Use `--summary` for all five step statuses or `--current` for the current step’s full renderer Instructions, Use, Policy Basis, commands, and next actions. Use `guide` before any unfamiliar create or status transition. It repeats the page guidance and reports required fields, fields required by a status, enum values, relationship types and candidates, Markdown slots, timing, and exact paths. Use `describe` only when you need the raw model definition.
20
+ Use `workflow --json` to get the shared assessments, complete checklist, Work Items, blockers, and recommended next action. Use `program-path --next --json` for the current lifecycle step. Use `guide` before any unfamiliar create or status transition. It reports required fields, fields required by a status, enum values, relationship types and candidates, Markdown slots, timing, and exact paths. Use `describe` only when you need the raw model definition.
21
+
22
+ After changing a lifecycle fact directly, review `reconcile --preview --json`. A candidate asks whether the change represents a real policy event. Supply the actual event date or timestamp, departure risk when relevant, and explicit confirmation before applying it.
19
23
 
20
24
  ## Choose the right record
21
25
 
@@ -94,6 +98,8 @@ JSON is for stable metadata used by validation, relationships, filters, schedule
94
98
 
95
99
  If `guide` marks a Markdown slot recommended, fill it before treating the deliverable as complete. Keep observations and report details in the source record’s Markdown. Create a Finding only for a confirmed gap that needs its own remediation lifecycle. Create an Action Item only when follow-up needs a separate assignee, deadline, and completion proof. Set each child record’s `sourceResourceId` to the record that produced it; do not maintain reverse Finding or Action Item arrays on the source. Do not put a report’s entire variable structure into new JSON fields.
96
100
 
101
+ When `guide` returns a collection review requirement, review the listed type-specific criteria and use `npx filegrc review-collection RESOURCE_TYPE --scaffold`. Fill the management conclusion, rationale, reviewer, and date, then preview and apply the payload. Do not invent `collectionRevision`; FileGRC calculates it from the current records and material Workspace scope. Any later change makes the confirmation stale and requires another review.
102
+
97
103
  Store a relationship only on its authoritative record. Control Tests store `auditId`; External Evidence stores `auditIds`; Commitments store `systemIds` and `controlIds`; Controls store `policyIds` and `requirementIds`; Risks store `controlIds`; Systems store their direct `vendorId`. Use `references` to inspect derived inbound links.
98
104
 
99
105
  Use explicit business dates. Git records when a file changed, but it does not replace `occurredOn`, `scheduledFor`, `completedOn`, `approvedOn`, or similar fields.
@@ -178,13 +184,15 @@ Use `get RESOURCE_ID --mutation` and `update` so JSON and Markdown change togeth
178
184
 
179
185
  ```sh
180
186
  npx filegrc obligations --json
181
- npx filegrc complete OBLIGATION_ID completion-mutation.json --expected-revision REVISION
187
+ npx filegrc complete OBLIGATION_ID --scaffold --window-start YYYY-MM-DD --completed-on YYYY-MM-DD > completion-mutation.json
188
+ npx filegrc complete OBLIGATION_ID completion-mutation.json
182
189
  npx filegrc trigger EVENT_TYPE --occurred-on YYYY-MM-DD --subject RESOURCE_ID --json
183
- npx filegrc complete-action ACTION_ITEM_ID completion-mutation.json --completed-on YYYY-MM-DD --expected-revision REVISION
190
+ npx filegrc complete-action ACTION_ITEM_ID --scaffold --completed-on YYYY-MM-DD > completion-mutation.json
191
+ npx filegrc complete-action ACTION_ITEM_ID completion-mutation.json --completed-on YYYY-MM-DD
184
192
  npx filegrc complete-event OBLIGATION_EVENT_ID --completed-on YYYY-MM-DD --expected-revision REVISION
185
193
  ```
186
194
 
187
- Read `REVISION` from `npx filegrc get RESOURCE_ID --mutation`. Run `obligations` before `trigger` to preview every Policy Event task, owner, deadline, and requested proof. Triggering creates the event and adds all linked Action Items to the Work Queue atomically. `complete` and `complete-action` validate the expected completion type and link the new record atomically. `complete-event` refuses to close the workflow until every action has its requested proof. For hour-based deadlines use `--occurred-at` with an RFC 3339 timestamp and timezone.
195
+ Fill the scaffold with the actual work, evidence, review, and every null or empty required value. Completion scaffolds include the target revision. For other updates, read `REVISION` from `npx filegrc get RESOURCE_ID --mutation`. Run `obligations` before `trigger` to preview every Policy Event task, owner, deadline, and requested proof. Triggering creates the event and adds all linked Action Items to the Work Queue atomically. `complete` and `complete-action` validate the expected completion type and link the new record atomically. `complete-event` refuses to close the workflow until every action has its requested proof. For hour-based deadlines use `--occurred-at` with an RFC 3339 timestamp and timezone.
188
196
 
189
197
  ## Audit work
190
198
 
@@ -0,0 +1,11 @@
1
+ {
2
+ "id": "appointment-independent-policy-reviewer",
3
+ "type": "appointment",
4
+ "title": "Independent Policy Reviewer",
5
+ "status": "planned",
6
+ "appointmentKind": "independent-policy-reviewer",
7
+ "scopeResourceIds": [
8
+ "workspace"
9
+ ],
10
+ "responsibilities": "Challenge and approve policies and governed documents independently from their owners. Assign a qualified external reviewer when no suitable internal reviewer is available."
11
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "collection-review-complementary-control",
3
+ "type": "collection-review",
4
+ "title": "Customer and provider responsibilities review",
5
+ "status": "planned",
6
+ "resourceType": "complementary-control",
7
+ "scopeResourceIds": [
8
+ "workspace"
9
+ ]
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "collection-review-framework",
3
+ "type": "collection-review",
4
+ "title": "Framework and criteria sources review",
5
+ "status": "planned",
6
+ "resourceType": "framework",
7
+ "scopeResourceIds": [
8
+ "workspace"
9
+ ]
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "collection-review-person",
3
+ "type": "collection-review",
4
+ "title": "Program participants review",
5
+ "status": "planned",
6
+ "resourceType": "person",
7
+ "scopeResourceIds": [
8
+ "workspace"
9
+ ]
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "collection-review-system",
3
+ "type": "collection-review",
4
+ "title": "Service and system boundary review",
5
+ "status": "planned",
6
+ "resourceType": "system",
7
+ "scopeResourceIds": [
8
+ "workspace"
9
+ ]
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "collection-review-vendor",
3
+ "type": "collection-review",
4
+ "title": "Vendor and subservice scope review",
5
+ "status": "planned",
6
+ "resourceType": "vendor",
7
+ "scopeResourceIds": [
8
+ "workspace"
9
+ ]
10
+ }
@@ -8,7 +8,6 @@
8
8
  "appointment-policy-owner"
9
9
  ],
10
10
  "version": "1.0",
11
- "effectiveOn": "{{effective_date}}",
12
11
  "audience": [
13
12
  "employees",
14
13
  "contractors"
@@ -24,5 +23,7 @@
24
23
  "document-incident-response-plan"
25
24
  ],
26
25
  "evidenceIds": [],
27
- "classificationId": "internal"
26
+ "classificationId": "internal",
27
+ "proposedEffectiveOn": "{{effective_date}}",
28
+ "programRole": "required"
28
29
  }
@@ -31,6 +31,8 @@ During a disruption, {{company_name}} will:
31
31
 
32
32
  ## Roles
33
33
 
34
+ These names describe recovery functions, not required job titles or separate Appointments. The current Policy Owner performs them by default and management delegates a function only when that matches how the organization actually recovers its services.
35
+
34
36
  ### Policy owner
35
37
 
36
38
  The current Policy Owner owns this plan and keeps it current. The Policy Owner may delegate response duties but remains accountable for the plan.
@@ -8,12 +8,13 @@
8
8
  "appointment-policy-owner"
9
9
  ],
10
10
  "version": "1.0",
11
- "effectiveOn": "{{effective_date}}",
12
11
  "audience": [
13
12
  "contractors"
14
13
  ],
15
14
  "controlIds": [
16
15
  "control-workforce-expectations"
17
16
  ],
18
- "classificationId": "internal"
17
+ "classificationId": "internal",
18
+ "proposedEffectiveOn": "{{effective_date}}",
19
+ "programRole": "conditional"
19
20
  }
@@ -8,7 +8,6 @@
8
8
  "appointment-policy-owner"
9
9
  ],
10
10
  "version": "1.0",
11
- "effectiveOn": "{{effective_date}}",
12
11
  "audience": [
13
12
  "contractors"
14
13
  ],
@@ -18,5 +17,7 @@
18
17
  "trainingIds": [
19
18
  "training-security-awareness"
20
19
  ],
21
- "classificationId": "internal"
20
+ "classificationId": "internal",
21
+ "proposedEffectiveOn": "{{effective_date}}",
22
+ "programRole": "conditional"
22
23
  }
@@ -8,7 +8,6 @@
8
8
  "appointment-policy-owner"
9
9
  ],
10
10
  "version": "1.0",
11
- "effectiveOn": "{{effective_date}}",
12
11
  "audience": [
13
12
  "data-owners",
14
13
  "system-owners"
@@ -18,5 +17,7 @@
18
17
  "control-data-classification-inventory",
19
18
  "control-data-retention-disposal"
20
19
  ],
21
- "classificationId": "internal"
20
+ "classificationId": "internal",
21
+ "proposedEffectiveOn": "{{effective_date}}",
22
+ "programRole": "conditional"
22
23
  }
@@ -8,12 +8,13 @@
8
8
  "appointment-policy-owner"
9
9
  ],
10
10
  "version": "1.0",
11
- "effectiveOn": "{{effective_date}}",
12
11
  "audience": [
13
12
  "employees"
14
13
  ],
15
14
  "controlIds": [
16
15
  "control-workforce-expectations"
17
16
  ],
18
- "classificationId": "internal"
17
+ "classificationId": "internal",
18
+ "proposedEffectiveOn": "{{effective_date}}",
19
+ "programRole": "conditional"
19
20
  }
@@ -8,12 +8,13 @@
8
8
  "appointment-policy-owner"
9
9
  ],
10
10
  "version": "1.0",
11
- "effectiveOn": "{{effective_date}}",
12
11
  "audience": [
13
12
  "employees"
14
13
  ],
15
14
  "controlIds": [
16
15
  "control-workforce-expectations"
17
16
  ],
18
- "classificationId": "internal"
17
+ "classificationId": "internal",
18
+ "proposedEffectiveOn": "{{effective_date}}",
19
+ "programRole": "conditional"
19
20
  }
@@ -8,7 +8,6 @@
8
8
  "appointment-policy-owner"
9
9
  ],
10
10
  "version": "1.0",
11
- "effectiveOn": "{{effective_date}}",
12
11
  "audience": [
13
12
  "employees"
14
13
  ],
@@ -18,5 +17,7 @@
18
17
  "trainingIds": [
19
18
  "training-security-awareness"
20
19
  ],
21
- "classificationId": "internal"
20
+ "classificationId": "internal",
21
+ "proposedEffectiveOn": "{{effective_date}}",
22
+ "programRole": "conditional"
22
23
  }
@@ -8,7 +8,6 @@
8
8
  "appointment-policy-owner"
9
9
  ],
10
10
  "version": "1.0",
11
- "effectiveOn": "{{effective_date}}",
12
11
  "audience": [
13
12
  "employees",
14
13
  "contractors"
@@ -24,5 +23,7 @@
24
23
  "document-business-continuity-disaster-recovery"
25
24
  ],
26
25
  "evidenceIds": [],
27
- "classificationId": "internal"
26
+ "classificationId": "internal",
27
+ "proposedEffectiveOn": "{{effective_date}}",
28
+ "programRole": "required"
28
29
  }
@@ -41,6 +41,8 @@ Severity considers affected data, systems, customers, privileges, duration, spre
41
41
 
42
42
  ## Roles and authority
43
43
 
44
+ These names describe response functions, not required job titles or separate Appointments. The current Policy Owner performs them by default and management delegates a function only when that matches how the organization actually responds.
45
+
44
46
  ### Reporter
45
47
 
46
48
  Anyone may report a suspected incident. Reporters preserve available evidence, stop unsafe activity when they can do so safely, and follow response instructions. They do not need proof before reporting.
@@ -9,5 +9,6 @@
9
9
  "appointment-policy-owner"
10
10
  ],
11
11
  "version": "0.1",
12
- "classificationId": "confidential"
12
+ "classificationId": "confidential",
13
+ "programRole": "required"
13
14
  }
@@ -9,5 +9,6 @@
9
9
  "appointment-policy-owner"
10
10
  ],
11
11
  "version": "0.1",
12
- "classificationId": "confidential"
12
+ "classificationId": "confidential",
13
+ "programRole": "required"
13
14
  }
@@ -9,5 +9,6 @@
9
9
  "appointment-policy-owner"
10
10
  ],
11
11
  "version": "0.1",
12
- "classificationId": "confidential"
12
+ "classificationId": "confidential",
13
+ "programRole": "conditional"
13
14
  }
@@ -9,5 +9,6 @@
9
9
  "appointment-policy-owner"
10
10
  ],
11
11
  "version": "0.1",
12
- "classificationId": "internal"
12
+ "classificationId": "internal",
13
+ "programRole": "required"
13
14
  }
@@ -9,4 +9,4 @@ An obligation is a reusable policy schedule or event template. It is not the rec
9
9
  - When an approved cadence changes, update the policy, control, and obligation together.
10
10
  - Pause or retire a template only when the underlying policy work no longer applies. Do not delete historical templates that explain prior periods.
11
11
 
12
- Use `npx filegrc obligations --json` to inspect calculated recurring work and preview every Policy Event task, owner, deadline, and requested proof. Read the Obligation revision with `npx filegrc get OBLIGATION_ID --mutation`, then use `npx filegrc complete OBLIGATION_ID completion-mutation.json --expected-revision REVISION` to create and link a dated occurrence in one validated write. Use `npx filegrc trigger EVENT_TYPE ...` only after the matching event occurs; it adds all configured Action Items to the Work Queue atomically.
12
+ Use `npx filegrc obligations --json` to inspect calculated recurring work and preview every Policy Event task, owner, deadline, and requested proof. Run `npx filegrc complete OBLIGATION_ID --scaffold --window-start YYYY-MM-DD --completed-on YYYY-MM-DD > completion-mutation.json`, fill the actual work and proof, then pass that file to `npx filegrc complete OBLIGATION_ID completion-mutation.json`. The scaffold includes the current Obligation revision, and the final command creates and links the dated occurrence in one validated write. Use `npx filegrc trigger EVENT_TYPE ...` only after the matching event occurs; it adds all configured Action Items to the Work Queue atomically.
@@ -8,11 +8,12 @@
8
8
  ],
9
9
  "policyKind": "corporate-conduct",
10
10
  "version": "1.0",
11
- "effectiveOn": "{{effective_date}}",
12
11
  "audience": [
13
12
  "employees",
14
13
  "contractors",
15
14
  "agents"
16
15
  ],
17
- "acknowledgementRequired": true
16
+ "acknowledgementRequired": true,
17
+ "proposedEffectiveOn": "{{effective_date}}",
18
+ "programRole": "conditional"
18
19
  }
@@ -8,10 +8,11 @@
8
8
  ],
9
9
  "policyKind": "information-security",
10
10
  "version": "1.0",
11
- "effectiveOn": "{{effective_date}}",
12
11
  "audience": [
13
12
  "employees",
14
13
  "contractors"
15
14
  ],
16
- "acknowledgementRequired": true
15
+ "acknowledgementRequired": true,
16
+ "proposedEffectiveOn": "{{effective_date}}",
17
+ "programRole": "alternative"
17
18
  }
@@ -8,7 +8,6 @@
8
8
  ],
9
9
  "policyKind": "information-security",
10
10
  "version": "1.0",
11
- "effectiveOn": "{{effective_date}}",
12
11
  "audience": [
13
12
  "employees",
14
13
  "contractors",
@@ -17,5 +16,7 @@
17
16
  "acknowledgementRequired": true,
18
17
  "relatedDocumentIds": [
19
18
  "document-data-retention-schedule"
20
- ]
19
+ ],
20
+ "proposedEffectiveOn": "{{effective_date}}",
21
+ "programRole": "required"
21
22
  }
@@ -8,7 +8,6 @@
8
8
  ],
9
9
  "policyKind": "workforce-conduct",
10
10
  "version": "1.0",
11
- "effectiveOn": "{{effective_date}}",
12
11
  "audience": [
13
12
  "employees"
14
13
  ],
@@ -16,5 +15,7 @@
16
15
  "relatedDocumentIds": [
17
16
  "document-employee-handbook-acknowledgement",
18
17
  "document-employee-policy-acknowledgement"
19
- ]
18
+ ],
19
+ "proposedEffectiveOn": "{{effective_date}}",
20
+ "programRole": "conditional"
20
21
  }
@@ -8,7 +8,6 @@
8
8
  ],
9
9
  "policyKind": "information-security",
10
10
  "version": "1.0",
11
- "effectiveOn": "{{effective_date}}",
12
11
  "audience": [
13
12
  "employees",
14
13
  "contractors",
@@ -24,5 +23,7 @@
24
23
  "document-business-continuity-disaster-recovery",
25
24
  "document-incident-response-plan",
26
25
  "document-data-retention-schedule"
27
- ]
26
+ ],
27
+ "proposedEffectiveOn": "{{effective_date}}",
28
+ "programRole": "required"
28
29
  }
@@ -28,7 +28,7 @@ The policy owner:
28
28
 
29
29
  An independent reviewer chairs the security and risk oversight group. This person must be separate from the policy owner and able to challenge the owner's decisions. The reviewer will usually be another leader or manager in the organization, but may be external. The reviewer approves policies and governed plans, challenges management's assessment of control operation, and records independent decisions.
30
30
 
31
- The security and risk oversight group meets at least quarterly to review the risk register, material incidents, significant findings, vendor and access review results, policy changes, exercises, and overdue work. Each meeting has formal minutes, decisions, and assigned actions. A one-person company must appoint a qualified external person to fill the independent reviewer role because no second internal person is available.
31
+ The security and risk oversight group meets at least quarterly to review the risk register, material incidents, significant findings, vendor and access review results, policy changes, exercises, and overdue work. Each meeting has formal minutes, decisions, and assigned actions. When no suitable internal independent reviewer is available, the organization appoints a qualified external person to fill the role.
32
32
 
33
33
  System and process owners classify their systems and data, approve access, maintain safeguards, respond to findings, and keep recovery information current.
34
34
 
@@ -8,10 +8,11 @@
8
8
  ],
9
9
  "policyKind": "information-security",
10
10
  "version": "1.0",
11
- "effectiveOn": "{{effective_date}}",
12
11
  "audience": [
13
12
  "employees",
14
13
  "contractors"
15
14
  ],
16
- "acknowledgementRequired": true
15
+ "acknowledgementRequired": true,
16
+ "proposedEffectiveOn": "{{effective_date}}",
17
+ "programRole": "supporting"
17
18
  }
@@ -5,6 +5,5 @@
5
5
  "showOnboarding": true,
6
6
  "repositoryMode": "trunk",
7
7
  "authoritativeBranch": "main",
8
- "repositoryRemote": "origin",
9
- "completedStagePageIds": []
8
+ "repositoryRemote": "origin"
10
9
  }
@@ -1,9 +1,9 @@
1
1
  # filegrc Program Repository
2
2
 
3
- This Git repository is the system of record for filegrc governance records and their revision history. It can supply the training and acknowledgement catalog, exception and finding populations, policy and document approvals, obligation history, Policy Event workflows, and management evidence indexes.
3
+ This Git repository is the system of record for filegrc governance records and their revision history. It can supply the training and acknowledgement catalog, exception and finding populations, policy and document approvals, risk register and assessments, vendor inventory and reviews, oversight records, obligation history, Policy Event workflows, and management evidence indexes.
4
4
 
5
5
  ## Evidence Extraction
6
6
 
7
7
  Run filegrc from a clean commit. Use resource dates and audit links to select the exact engagement date or period, save the query or agent instructions with the export, and retain the fixed result behind an evidence record. Record a zero count when the committed source query returns no relevant items.
8
8
 
9
- The repository is authoritative only for records stored here. Identity, workforce, source-control, deployment, monitoring, endpoint, backup, vulnerability, and vendor systems remain authoritative for the activity they perform.
9
+ The repository is authoritative only for records stored here. Identity, workforce, source-control, deployment, monitoring, endpoint, backup, vulnerability, and external vendor-management systems remain authoritative for the activity they perform.
@@ -1,5 +1,5 @@
1
1
  {
2
- "dataModelVersion": "2",
2
+ "dataModelVersion": "3",
3
3
  "id": "workspace",
4
4
  "type": "workspace",
5
5
  "title": "{{program_title}}",
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "{{project_name}}",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
4
4
  "private": true,
5
5
  "description": "filegrc workspace for a SOC 2 program",
6
6
  "type": "module",
7
7
  "scripts": {
8
8
  "serve": "filegrc serve",
9
9
  "build": "filegrc build",
10
- "validate": "filegrc validate"
10
+ "validate": "filegrc validate",
11
+ "check:milestone": "filegrc milestone-check"
11
12
  },
12
13
  "dependencies": {
13
14
  "filegrc": "{{filegrc_version_range}}"