filegrc 0.3.3 → 0.4.0
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.
- package/README.md +17 -7
- package/model/index.js +37 -3
- package/model/v1.json +89 -52
- package/model/v2.json +8022 -0
- package/package.json +1 -1
- package/src/agent.js +36 -8
- package/src/audit-preparation.js +63 -60
- package/src/cli.js +176 -113
- package/src/coverage.js +50 -0
- package/src/evidence-packet.js +115 -75
- package/src/files.js +230 -28
- package/src/git-name.js +16 -0
- package/src/git.js +702 -6
- package/src/index.js +9 -6
- package/src/model-docs.js +88 -7
- package/src/model-migration.js +1463 -0
- package/src/mutation.js +46 -1
- package/src/obligations.js +108 -84
- package/src/parties.js +17 -2
- package/src/program-path.js +31 -58
- package/src/program-readiness.js +142 -106
- package/src/resource-status.js +17 -0
- package/src/server.js +175 -36
- package/src/setup.js +27 -28
- package/src/state.js +93 -27
- package/src/timing.js +41 -0
- package/src/validate.js +611 -43
- package/src/web.js +586 -141
- package/src/workspace.js +15 -7
- package/src/evidence-tests.js +0 -69
package/src/index.js
CHANGED
|
@@ -3,9 +3,9 @@ export { buildAgentGuide, findResourceReferences, listResourceTypes, scaffoldRes
|
|
|
3
3
|
export { assessAuditPreparation, prepareAuditWorkspace } from "./audit-preparation.js";
|
|
4
4
|
export { buildWorkspace } from "./build.js";
|
|
5
5
|
export { generateEvidencePacket, prepareEvidencePacket, writeEvidencePacket } from "./evidence-packet.js";
|
|
6
|
-
export { ensureEvidenceTestDrafts, planEvidenceTestDrafts } from "./evidence-tests.js";
|
|
7
6
|
export {
|
|
8
7
|
addEvidenceAttachment,
|
|
8
|
+
applyResourceBatch,
|
|
9
9
|
createResource,
|
|
10
10
|
createResourceAndLink,
|
|
11
11
|
createResources,
|
|
@@ -18,14 +18,18 @@ export {
|
|
|
18
18
|
export {
|
|
19
19
|
commitAndPushWorkspace,
|
|
20
20
|
commitWorkspace,
|
|
21
|
+
getBrowserRepositoryState,
|
|
21
22
|
getFileHistory,
|
|
22
23
|
getGitSummary,
|
|
23
24
|
getWorkspaceHistories,
|
|
24
25
|
pullWorkspace,
|
|
25
|
-
pushWorkspace
|
|
26
|
+
pushWorkspace,
|
|
27
|
+
retryBrowserSync,
|
|
28
|
+
runBrowserMutation
|
|
26
29
|
} from "./git.js";
|
|
27
30
|
export { generateModelDocumentation } from "./model-docs.js";
|
|
28
31
|
export { renderMarkdown } from "./markdown.js";
|
|
32
|
+
export { migrateModel, planModelMigration } from "./model-migration.js";
|
|
29
33
|
export {
|
|
30
34
|
completeObligationAction,
|
|
31
35
|
completeObligationEvent,
|
|
@@ -33,11 +37,9 @@ export {
|
|
|
33
37
|
createObligationEvent,
|
|
34
38
|
planObligations
|
|
35
39
|
} from "./obligations.js";
|
|
36
|
-
export { assessProgramReadiness } from "./program-readiness.js";
|
|
40
|
+
export { assessEvidenceMap, assessProgramReadiness } from "./program-readiness.js";
|
|
37
41
|
export {
|
|
38
42
|
buildAgentProgramPath,
|
|
39
|
-
policyEventName,
|
|
40
|
-
POLICY_EVENT_NAMES,
|
|
41
43
|
PROGRAM_PATH,
|
|
42
44
|
RESOURCE_INSTRUCTIONS,
|
|
43
45
|
resourceProgramContext
|
|
@@ -50,9 +52,10 @@ export {
|
|
|
50
52
|
nextCalendarOccurrence
|
|
51
53
|
} from "./recurrence.js";
|
|
52
54
|
export { searchResources, searchableValues } from "./search.js";
|
|
55
|
+
export { effectiveResourceStatus } from "./resource-status.js";
|
|
53
56
|
export { createFilegrcServer, serveWorkspace } from "./server.js";
|
|
54
57
|
export { normalizeSetupPayload, planWorkspaceSetup, setupWorkspace, summarizeSetupResult } from "./setup.js";
|
|
55
|
-
export { createAppState } from "./state.js";
|
|
58
|
+
export { createAppState, createResourceDetail } from "./state.js";
|
|
56
59
|
export { currentCalendarDate, formatCalendarDate, formatLocalDateTime } from "./time.js";
|
|
57
60
|
export { validateWorkspace } from "./validate.js";
|
|
58
61
|
export { indexResources, loadWorkspace } from "./workspace.js";
|
package/src/model-docs.js
CHANGED
|
@@ -15,7 +15,7 @@ export function generateModelDocumentation(model) {
|
|
|
15
15
|
"",
|
|
16
16
|
"## Program path",
|
|
17
17
|
"",
|
|
18
|
-
"The renderer, CLI, generated agent instructions, and this reference use the same
|
|
18
|
+
"The renderer, CLI, generated agent instructions, and this reference use the same five-step lifecycle:",
|
|
19
19
|
"",
|
|
20
20
|
...programPath.flatMap((stage) => [
|
|
21
21
|
`### Step ${stage.number}. ${stage.title}`,
|
|
@@ -35,6 +35,52 @@ export function generateModelDocumentation(model) {
|
|
|
35
35
|
...stage.commands.map((command) => `- \`${command}\``),
|
|
36
36
|
""
|
|
37
37
|
]),
|
|
38
|
+
"## Relation groups",
|
|
39
|
+
"",
|
|
40
|
+
"Relationship fields use the named groups below. The registry expands each group to explicit resource types, so no relationship accepts an unrestricted wildcard.",
|
|
41
|
+
"",
|
|
42
|
+
"| Group | Resource types |",
|
|
43
|
+
"| --- | --- |",
|
|
44
|
+
...Object.entries(model.relationGroups || {}).map(([name, types]) => (
|
|
45
|
+
`| \`${name}\` | ${types.map((type) => `\`${type}\``).join(", ")} |`
|
|
46
|
+
)),
|
|
47
|
+
"",
|
|
48
|
+
"## Relationship constraints",
|
|
49
|
+
"",
|
|
50
|
+
"Relationship constraints prevent cycles and duplicate active authority or access records.",
|
|
51
|
+
"",
|
|
52
|
+
...((model.relationshipConstraints?.acyclic || []).map((constraint) => (
|
|
53
|
+
`- \`${constraint.resourceType}.${constraint.field}\` must be acyclic.`
|
|
54
|
+
))),
|
|
55
|
+
...((model.relationshipConstraints?.unique || []).map((constraint) => (
|
|
56
|
+
`- \`${constraint.resourceType}\` records in ${constraint.statuses.map((status) => `\`${status}\``).join(", ")} must be unique by ${constraint.fields.map((field) => `\`${field}\``).join(", ")}.`
|
|
57
|
+
))),
|
|
58
|
+
"",
|
|
59
|
+
"## Obligation activities",
|
|
60
|
+
"",
|
|
61
|
+
"The model owns each activity name, allowed recurrence modes and scope types, its default completion record, and every record type that can prove completion.",
|
|
62
|
+
"",
|
|
63
|
+
"| Activity | Title | Recurrence | Scope resource types | Default completion | Accepted completion records |",
|
|
64
|
+
"| --- | --- | --- | --- | --- | --- |",
|
|
65
|
+
...Object.entries(model.obligationActivities || {}).map(([name, activity]) => (
|
|
66
|
+
`| \`${name}\` | ${escapeCell(activity.title)} | ${activity.recurrenceModes.map((mode) => `\`${mode}\``).join(", ")} | ${activity.scopeResourceTypes.map((type) => `\`${type}\``).join(", ")} | \`${activity.completionType}\` | ${activity.completionResourceTypes.map((type) => `\`${type}\``).join(", ")} |`
|
|
67
|
+
)),
|
|
68
|
+
"",
|
|
69
|
+
"## Policy events",
|
|
70
|
+
"",
|
|
71
|
+
"The model owns each event title and the minimum and maximum count for each subject resource type.",
|
|
72
|
+
"",
|
|
73
|
+
"| Event | Title | Subject rules |",
|
|
74
|
+
"| --- | --- | --- |",
|
|
75
|
+
...Object.entries(model.policyEvents || {}).map(([name, event]) => (
|
|
76
|
+
`| \`${name}\` | ${escapeCell(event.title)} | ${event.subjectRules.map(({ resourceType, minimum = 0, maximum }) => `\`${resourceType}\` ${minimum}..${Number.isInteger(maximum) ? maximum : "*"}`).join(", ")} |`
|
|
77
|
+
)),
|
|
78
|
+
"",
|
|
79
|
+
"## Nested object schemas",
|
|
80
|
+
"",
|
|
81
|
+
"Named object schemas reject unknown keys unless the schema explicitly allows a typed map or arbitrary JSON. Conditional properties are valid only for the selected discriminator.",
|
|
82
|
+
"",
|
|
83
|
+
...Object.entries(model.objectTypes || {}).flatMap(([name, schema]) => objectTypeDocumentation(name, schema)),
|
|
38
84
|
"## Common fields",
|
|
39
85
|
"",
|
|
40
86
|
"| Field | Type | Required | Meaning |",
|
|
@@ -53,7 +99,7 @@ export function generateModelDocumentation(model) {
|
|
|
53
99
|
"",
|
|
54
100
|
"## Program and audit readiness defaults",
|
|
55
101
|
"",
|
|
56
|
-
"Program Readiness checks management scope, policy adoption, control implementation,
|
|
102
|
+
"Program Readiness checks management scope, policy adoption, control implementation, and authoritative evidence mapping without requiring an audit record. Audit Readiness starts after a CPA firm is engaged and uses the defaults below to prepare Type 1 and Type 2 fieldwork.",
|
|
57
103
|
"",
|
|
58
104
|
"Management documents:",
|
|
59
105
|
"",
|
|
@@ -66,9 +112,9 @@ export function generateModelDocumentation(model) {
|
|
|
66
112
|
"Authoritative systems of record:",
|
|
67
113
|
"",
|
|
68
114
|
...model.evidenceSourceFamilies.map((item) => (
|
|
69
|
-
item.
|
|
70
|
-
? `- **${item.title}** (${item.sourceKinds.map((kind) => `\`${kind}\``).join(", ")}): ${item.description}
|
|
71
|
-
: `- **${item.title}** (${item.sourceKinds.map((kind) => `\`${kind}\``).join(", ")}): ${item.description}
|
|
115
|
+
item.filegrcManaged === true
|
|
116
|
+
? `- **${item.title}** (${item.sourceKinds.map((kind) => `\`${kind}\``).join(", ")}): ${item.description} FileGRC operating records: ${item.operationRecordTypes.map((type) => `\`${type}\``).join(", ")}. Expected evidence: ${item.evidencePrompt} ${item.timing}`
|
|
117
|
+
: `- **${item.title}** (${item.sourceKinds.map((kind) => `\`${kind}\``).join(", ")}): ${item.description} Expected evidence: ${item.evidencePrompt} ${item.timing}`
|
|
72
118
|
)),
|
|
73
119
|
"",
|
|
74
120
|
"## Resource groups",
|
|
@@ -143,7 +189,12 @@ function choiceLabel(name) {
|
|
|
143
189
|
}
|
|
144
190
|
|
|
145
191
|
function fieldType(field) {
|
|
146
|
-
if (field.type === "array")
|
|
192
|
+
if (field.type === "array") {
|
|
193
|
+
return field.itemObjectType
|
|
194
|
+
? `array of object (\`${field.itemObjectType}\`)`
|
|
195
|
+
: `array of ${field.items ?? "values"}`;
|
|
196
|
+
}
|
|
197
|
+
if (field.type === "object" && field.objectType) return `object (\`${field.objectType}\`)`;
|
|
147
198
|
return field.format && field.format !== field.type ? `${field.type} (${field.format})` : field.type;
|
|
148
199
|
}
|
|
149
200
|
|
|
@@ -151,14 +202,44 @@ function fieldNotes(field) {
|
|
|
151
202
|
return [
|
|
152
203
|
field.label,
|
|
153
204
|
field.values ? `Values: ${field.values.map((item) => `\`${item}\``).join(", ")}` : "",
|
|
205
|
+
field.registry ? `Values come from the \`${field.registry}\` registry.` : "",
|
|
206
|
+
field.relationGroup ? `Relation group: \`${field.relationGroup}\`.` : "",
|
|
154
207
|
field.relation ? `References: ${field.relation.map((item) => `\`${item}\``).join(", ")}` : "",
|
|
155
208
|
field.minimum !== undefined ? `Minimum: \`${field.minimum}\`.` : "",
|
|
156
209
|
field.maximum !== undefined ? `Maximum: \`${field.maximum}\`.` : "",
|
|
210
|
+
field.managed ? "Managed by filegrc." : "",
|
|
157
211
|
field.disjointFrom ? `Must not overlap \`${field.disjointFrom}\`.` : "",
|
|
158
|
-
field.requiredWhen ? `Required when ${
|
|
212
|
+
field.requiredWhen ? `Required when ${conditionText(field.requiredWhen)}.` : "",
|
|
213
|
+
field.allowedWhen ? `Allowed when ${conditionText(field.allowedWhen)}.` : ""
|
|
159
214
|
].filter(Boolean).join(" ");
|
|
160
215
|
}
|
|
161
216
|
|
|
217
|
+
function objectTypeDocumentation(name, schema) {
|
|
218
|
+
const lines = [`### \`${name}\``, ""];
|
|
219
|
+
const properties = Object.entries(schema.properties || {});
|
|
220
|
+
if (properties.length) {
|
|
221
|
+
const required = new Set(schema.required || []);
|
|
222
|
+
lines.push("| Property | Type | Required | Notes |", "| --- | --- | --- | --- |");
|
|
223
|
+
for (const [propertyName, property] of properties) {
|
|
224
|
+
const requiredLabel = required.has(propertyName)
|
|
225
|
+
? "Yes"
|
|
226
|
+
: property.requiredWhen
|
|
227
|
+
? "Conditional"
|
|
228
|
+
: "No";
|
|
229
|
+
lines.push(`| \`${propertyName}\` | ${fieldType(property)} | ${requiredLabel} | ${escapeCell(fieldNotes(property))} |`);
|
|
230
|
+
}
|
|
231
|
+
} else if (schema.additionalProperties === true) {
|
|
232
|
+
lines.push("Allows arbitrary JSON properties.");
|
|
233
|
+
} else if (schema.additionalProperties) {
|
|
234
|
+
lines.push(`Allows dynamic keys whose values are ${fieldType(schema.additionalProperties)}.`);
|
|
235
|
+
} else {
|
|
236
|
+
lines.push("Does not allow properties.");
|
|
237
|
+
}
|
|
238
|
+
if (schema.keyFormat) lines.push("", `Key format: \`${schema.keyFormat}\`.`);
|
|
239
|
+
lines.push("");
|
|
240
|
+
return lines;
|
|
241
|
+
}
|
|
242
|
+
|
|
162
243
|
function escapeCell(value) {
|
|
163
244
|
return String(value).replaceAll("|", "\\|").replaceAll("\n", " ");
|
|
164
245
|
}
|