filegrc 0.16.17 → 0.16.18

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "filegrc",
3
- "version": "0.16.17",
3
+ "version": "0.16.18",
4
4
  "description": "Zero-dependency Git-native GRC engine",
5
5
  "license": "MIT",
6
6
  "repository": {
package/src/agent.js CHANGED
@@ -122,13 +122,15 @@ export function buildAgentGuide(loaded, type, options = {}) {
122
122
  oneOf: definition.oneOf ?? [],
123
123
  markdown,
124
124
  workflow: [
125
- "Inspect existing records and relation candidates before writing.",
125
+ "Inspect the recommended action, existing records, relationships, source Markdown, and available evidence. Do the research, drafting, record edits, and validation you can do yourself.",
126
126
  definition.singleton
127
127
  ? "Open the existing singleton record and update only gaps supported by facts from an authoritative source."
128
128
  : "Reuse and update a suitable existing record. Create a scaffold only when no record covers the work, then replace every null value and empty required array with facts from an authoritative source.",
129
129
  recommendedMarkdown.length
130
130
  ? "Keep model fields in JSON and use the recommended Markdown companion for the detailed work, decisions, results, exceptions, and follow-up that apply to this record."
131
131
  : "Keep the current facts and lifecycle state in JSON. Add optional Record Markdown only when the model fields cannot explain the record clearly.",
132
+ "If a material fact, external action, approval, or management decision is still missing, ask the user one specific question. State what you inspected, the exact missing input, and what it unlocks. Do not hand off FileGRC commands, routine record entry, or a vague request to confirm. Continue the workflow after the answer without asking for another handoff.",
133
+ ...(type === "control" ? ["Separate implementation from operation: document the working configuration, scope, owner, procedure, source, and enabled rules when its operation pattern needs them before marking Implemented. Record dated operating work and evidence only after a real cycle or event occurs; a ready schedule is not proof of operation."] : []),
132
134
  ...(type === "program" && modelSupports(loaded.model, "program-scope")
133
135
  ? ["Review Requirement applicability with npx filegrc review-applicability --type requirement --scaffold, then preview and apply the reviewed decisions as one validated batch."]
134
136
  : []),
package/src/cli.js CHANGED
@@ -1743,7 +1743,7 @@ function agentOverview(model) {
1743
1743
  commit: "git diff --check && git diff && git add <reviewed-paths> && git commit -m <reason>"
1744
1744
  };
1745
1745
  return {
1746
- rule: "Treat data/ as the source of truth. Run guide before creating an unfamiliar type, validate after every write, review the Git diff, then commit a focused change.",
1746
+ rule: "Treat data/ as the source of truth. Inspect existing records and sources, then do the research, edits, and validation you can do. Ask the user only for a specific material fact, external action, approval, or decision you cannot establish; explain what it unlocks and continue after the answer. Run guide before creating an unfamiliar type, validate every write, review the Git diff, and commit a focused change.",
1747
1747
  programPath: buildAgentProgramPath(model),
1748
1748
  actions: Object.fromEntries(Object.entries(commands).map(([name, command]) => [
1749
1749
  name,
@@ -4,11 +4,11 @@ export const RESOURCE_INSTRUCTIONS = {
4
4
  program: "Set the Program goal, owners, Systems, Frameworks, criteria decisions, and risk method.",
5
5
  person: "Record the person’s actual job title and current status.",
6
6
  appointment: "Assign a named authority to one Person with its start date and scope.",
7
- team: "Confirm the Team’s members and chair.",
7
+ team: "Use the current Person and Appointment records to set the Team’s members and chair; ask who holds a role only when those sources cannot establish it.",
8
8
  system: "Define the service boundary, exclusions, owners, and information it handles.",
9
9
  component: "Record a material service or evidence source and its role in each linked System.",
10
10
  vendor: "Record each material external provider and the Components it supplies.",
11
- classification: "Confirm the handling categories and apply them to information and evidence.",
11
+ classification: "Use current Policy content and recorded information needs to propose handling categories, then apply the management decision to information and evidence. Ask about any category those sources do not settle.",
12
12
  "information-type": "Name a stable category of information, set its default Classification, and link its uses.",
13
13
  framework: "Select the criteria Framework and version used by the Program.",
14
14
  requirement: "Review whether this criterion applies to the Program and record the decision and rationale.",
@@ -22,7 +22,7 @@ export const RESOURCE_INSTRUCTIONS = {
22
22
  evidence: "Record a real artifact or approved reference, link its source and supported work, then have another person verify it.",
23
23
  "risk-assessment": "Assess the in-scope service, record conclusions, and obtain an independent review.",
24
24
  risk: "Name the threat and impact, assign an owner, rate the risk, and record its response.",
25
- obligation: "Confirm the owner, cadence or trigger, deadline, and proof, then enable the rule when its Control is ready.",
25
+ obligation: "Read the linked Policy and Control, fill the owner, cadence or trigger, deadline, and proof from those sources, then enable the rule when its Control is ready. Ask only for an unresolved management choice.",
26
26
  "retention-schedule-item": "Set the Information Types, scope, cutoff, period, disposition, and sources for one retention rule.",
27
27
  "obligation-event": "Record the actual event date and subject, then complete its linked Work Queue actions.",
28
28
  "policy-review": "Record the review date, reviewer, decision, and any required follow-up.",
@@ -101,11 +101,11 @@ export const RESOURCE_OUTPUTS = {
101
101
  };
102
102
 
103
103
  export const RESOURCE_PAGE_SUMMARIES = {
104
- person: "Confirm who works on the program.",
104
+ person: "Use current people already recorded; ask for a missing person's identity or role only when needed.",
105
105
  appointment: "Assign named authority.",
106
- team: "Confirm shared owners and members.",
106
+ team: "Set shared owners and members from current People and Appointments.",
107
107
  program: "Choose the goal, scope, criteria, controls, owners, and risk method.",
108
- framework: "Confirm the SOC 2 framework.",
108
+ framework: "Select the applicable SOC 2 framework and version from the installed catalog.",
109
109
  requirement: "Decide which SOC 2 criteria apply.",
110
110
  commitment: "Record customer promises that affect scope.",
111
111
  "requirement-mapping": "Review how supplemental promises relate to Requirements and Controls.",
@@ -134,8 +134,8 @@ export const PROGRAM_PATH = [
134
134
  description: "Ownership, criteria, and service boundary",
135
135
  summary: "A reviewed Program scope with owners, criteria, Systems, and material providers.",
136
136
  sections: [
137
- { id: "ownership", title: "Program Ownership", description: "Confirm who owns the program, plus the normal security reporting channel and its fallback.", steps: ["Confirm the program lead, policy owner, independent reviewer, and oversight team.", "Replace the reporting-channel placeholders with real normal and fallback routes, then commit the proposal."], types: ["person", "appointment", "team", "reporting-route-set"], defaultOpen: true },
138
- { id: "criteria", title: "Program and Criteria", description: "Define the Program, confirm its Frameworks, record Program-scoped Requirement applicability, and connect customer commitments that shape the System or Control design.", steps: ["Set the Program goal, owners, risk method, and tentative timing.", "Review each selected criterion for this service and record its applicability decision.", "Replace the starter Commitment prompt with the real promise; add only needed supplemental mappings."], types: ["program", "framework", "requirement", "commitment", "requirement-mapping"], defaultOpen: true },
137
+ { id: "ownership", title: "Program Ownership", description: "Assign program owners and set the normal security reporting channel and its fallback.", steps: ["Inspect current People and Appointments, then assign the program lead, policy owner, independent reviewer, and oversight team. Ask only for missing assignments.", "Use the actual normal and fallback routes to replace reporting-channel placeholders, then commit the proposal."], types: ["person", "appointment", "team", "reporting-route-set"], defaultOpen: true },
138
+ { id: "criteria", title: "Program and Criteria", description: "Define the Program, select its Frameworks, record Program-scoped Requirement applicability, and connect customer commitments that shape the System or Control design.", steps: ["Set the Program goal, owners, risk method, and tentative timing from current records; ask for unresolved management choices.", "Compare each selected criterion with the service scope and record its applicability decision.", "Replace the starter Commitment prompt with the actual promise; add only needed supplemental mappings."], types: ["program", "framework", "requirement", "commitment", "requirement-mapping"], defaultOpen: true },
139
139
  { id: "boundary", title: "System Boundary", description: "Start with the bounded System. Add Components that materially deliver the service, support Controls, produce authoritative Evidence, or support relevant operations. Keep Vendor relationships and specific Assets separate.", steps: ["Define the service and exclusions in a bounded System selected by the Program.", "Add material Components and Vendors with their actual System relationships.", "Record the Information Types and Classifications the service uses."], types: ["system", "component", "vendor", "classification", "information-type"], defaultOpen: false }
140
140
  ],
141
141
  resourceTypes: ["person", "appointment", "team", "reporting-route-set", "program", "framework", "requirement", "commitment", "requirement-mapping", "system", "component", "vendor", "classification", "information-type"],
@@ -160,7 +160,7 @@ export const PROGRAM_PATH = [
160
160
  description: "Approve governed content and retention decisions",
161
161
  summary: "Approved Policies, program Documents, Training content, and retention decisions.",
162
162
  sections: [
163
- { id: "policy-content", title: "Policies", description: "Approve the program's governing content.", instructions: "Open each Policy, program Document, and Training record. Replace placeholders, confirm the owner and intended values, then have a separate person approve the exact Markdown revision.", output: "Approved content bound to the reviewed revisions.", steps: ["Replace placeholders with the company's real rules, plans, and training material.", "Confirm the owner, separate approver, linked Controls, audience, and intended values.", "Record the independent approval and date against each exact Markdown revision."], types: [], relatedLinks: [{ type: "policy", label: "Policies", href: "#/policies" }], defaultOpen: true },
163
+ { id: "policy-content", title: "Policies", description: "Approve the program's governing content.", instructions: "Open each Policy, program Document, and Training record. Draft from current approved decisions, replace placeholders, and resolve only material choices with management. A separate person then approves the exact Markdown revision.", output: "Approved content bound to the reviewed revisions.", steps: ["Draft the company's real rules, plans, and training material from current scope and approved decisions.", "Resolve missing owner, separate approver, Control links, audience, or intended values from authoritative records; ask only when a material decision remains.", "Have the independent approver review the exact Markdown revision and record their actual decision and date."], types: [], relatedLinks: [{ type: "policy", label: "Policies", href: "#/policies" }], defaultOpen: true },
164
164
  { id: "retention", title: "Data Retention Schedule", description: "Approve the schedule document and its completed rows together.", steps: ["Review the governing schedule and any legal hold or exception rules.", "Complete a row for each distinct information use, cutoff, retention period, and disposition.", "Have a separate reviewer approve the complete document and row set."], types: [], utility: "retention-schedule", defaultOpen: true }
165
165
  ],
166
166
  resourceTypes: [],
@@ -184,7 +184,7 @@ export const PROGRAM_PATH = [
184
184
  description: "Implement and prepare to operate",
185
185
  summary: "Implemented Controls with ready evidence sources and enabled work schedules.",
186
186
  sections: [
187
- { id: "controls", title: "Controls", description: "Put each selected Control into use and record what is actually in place.", steps: ["Open each Control for its specific setup action and current missing checks.", "Configure the activity and record its procedure, Systems, owner, and evidence sources.", "Mark it Implemented with its real start date after its sources and schedules are ready."], types: ["control"], defaultOpen: true },
187
+ { id: "controls", title: "Controls", description: "Put each selected Control into use and record its working design. Dated operating proof follows when work occurs.", steps: ["Open each Control, linked records, and current missing checks; do the setup that can be established from those sources.", "Configure the activity and record its procedure, Systems, owner, evidence sources, and any work rules its operation pattern requires.", "Mark it Implemented with its real start date when it works. Record later cycles and events separately with dated proof."], types: ["control"], defaultOpen: true },
188
188
  { id: "complementary-controls", title: "Complementary Controls", description: "Record customer or provider responsibilities that form part of the implementation boundary, or confirm there are none.", steps: ["Identify any customer or carved-out provider action an in-scope Control depends on.", "Record each dependency, or confirm that the current scope has none."], types: ["complementary-control"], defaultOpen: true },
189
189
  { id: "evidence-sources", title: "Evidence Sources", description: "Check that every Control points to an authoritative source that can produce its expected evidence.", steps: ["For each Control family, link an active Component with the required source kind, access owners, and retrieval instructions."], types: [], utility: "evidence-sources", defaultOpen: true },
190
190
  { id: "obligations", title: "Obligations", description: "Configure the calendar and event schedules that operate the Controls.", steps: ["Check the owner, trigger or cadence, due window, and required proof for each Obligation.", "Enable the rules that will run the implemented Controls."], types: ["obligation"], defaultOpen: true }
@@ -217,7 +217,7 @@ export async function assessProgramReadiness(input, options = {}) {
217
217
  ? item
218
218
  : { ...item, status: "blocked", message: `Complete the Control collection review before activation. ${item.message}` };
219
219
  }));
220
- controlStage.description = `Each implemented Control needs an owner, actual procedure, scope, operation pattern, mappings, an implementation date, enabled Obligations, and complete authoritative source ${modelSupports(loaded.model, "component-sources") ? "Components" : "Systems"}. When implementation is ready, perform one review of the implemented Control collection. Management then activates the unchanged approved program content as the Step 3 cutover.`;
220
+ controlStage.description = `Each implemented Control needs an owner, actual procedure, scope, operation pattern, mappings, an implementation date, enabled Obligations for scheduled or event work, and complete authoritative source ${modelSupports(loaded.model, "component-sources") ? "Components" : "Systems"}. When implementation is ready, perform one review of the implemented Control collection. Management then activates the unchanged approved program content as the Step 3 cutover.`;
221
221
  const scopeReadinessStage = scopeStage(
222
222
  program,
223
223
  scope,
@@ -596,7 +596,7 @@ function scopeStage(workspace, scope, records, byId, model, collectionReviews =
596
596
  items.push(item(
597
597
  "criteria",
598
598
  criteriaComplete ? "complete" : "action",
599
- "Confirm Trust Services criteria, Description Criteria, and Controls",
599
+ "Resolve criteria decisions and Control coverage",
600
600
  criteriaComplete
601
601
  ? `${selectedTrustServicesRequirements.length} applicable Trust Services criteria, ${selectedDescriptionRequirements.length} SOC 2 Description Criteria, and ${scope.controls.length} Controls are in scope. Every applicable Trust Services criterion has at least one selected Control; Description Criteria govern the system description and do not map to Controls.`
602
602
  : missingRequiredSecurityReferences.length || missingRequiredDescriptionReferences.length
@@ -992,7 +992,7 @@ function programOwnershipItem(records, byId) {
992
992
  return item(
993
993
  "program-ownership",
994
994
  complete ? "complete" : "action",
995
- "Confirm program owners and oversight",
995
+ "Assign program owners and oversight",
996
996
  complete
997
997
  ? `${currentOwners.size} current ${currentOwners.size === 1 ? "person owns" : "people own"} the program records.${oversight ? " Security and Risk Oversight has a separate current chair." : ""}`
998
998
  : detail.join(" "),
@@ -1619,7 +1619,7 @@ function policyActivationItem(assessment) {
1619
1619
  [assessment.unresolvedExceptionIds.length, "unresolved Exceptions"]
1620
1620
  ].filter(([count]) => count).map(([count, label]) => `${count} ${label}`);
1621
1621
  const message = assessment.state === "active-and-operating"
1622
- ? `Active and effective ${assessment.effectiveOn}; all ${assessment.linkedControlIds.length} linked Controls are implemented with Components, evidence sources, and enabled Obligations.`
1622
+ ? `Active and effective ${assessment.effectiveOn}; all ${assessment.linkedControlIds.length} linked Controls are implemented with Components, evidence sources, and enabled Obligations where scheduled or event work requires them.`
1623
1623
  : assessment.state === "ready-to-activate"
1624
1624
  ? "Implementation checks are complete. Include this approved Policy in the Step 3 cutover when you are ready for it to take effect."
1625
1625
  : `${assessment.label}: ${counts.join(", ") || assessment.timingWarnings.join(" ")}. ${assessment.activationWarning || ""}`.trim();
@@ -2128,7 +2128,7 @@ const starterControlChecks = {
2128
2128
  "control-monitoring-remediation": "Schedule the first Control review. Name who will inspect incidents, tests, Exceptions, overdue work, and follow-up closure when those records exist.",
2129
2129
  "control-access-authorization": "Open access lists for in-scope Systems and Vendor tools. Check that accounts use unique identities and only needed permissions, and new grants require a business reason and approval.",
2130
2130
  "control-strong-authentication": "Open the System and Vendor lists. For each tool used for production, source code, email, identity, or sensitive data, check MFA, unique accounts, default credentials, and admin roles.",
2131
- "control-access-review-offboarding": "Confirm access lists can be exported from key Systems and Vendor tools. Assign the first access review and the owner who will remove access when a departure occurs.",
2131
+ "control-access-review-offboarding": "Check whether key Systems and Vendor tools can export access lists. Set the first access review and name who removes access after a departure.",
2132
2132
  "control-physical-workspace-security": "Walk through actual work areas and visitor access. Check who can enter nonpublic spaces and how devices, papers, screens, and conversations are protected.",
2133
2133
  "control-data-classification-inventory": "List important data stores in Systems and Vendor tools. Check each has an owner, classification, approved purpose, and recorded location.",
2134
2134
  "control-encryption-transmission": "For Systems, Vendor tools, and devices holding Confidential or Restricted data, check encryption at rest and in transit and who can manage the keys.",
@@ -2154,16 +2154,16 @@ export function controlImplementationSteps(control, checks, options = {}) {
2154
2154
  if (!checks.implemented) steps.push(control.id === "control-strong-authentication" && options.targets?.length
2155
2155
  ? `Ensure MFA and unique accounts are enabled for ${options.targets.join(", ")}; check default credentials and admin roles.`
2156
2156
  : starterControlChecks[control.id]
2157
- || "Inspect the systems, people, vendors, or work this Control covers. Compare current practice with its statement and fix any gaps.");
2157
+ || `Inspect the Systems, people, Vendors, and work linked to ${control.title || control.id}. Compare the actual configuration with this Control's statement and fix the specific gaps.`);
2158
2158
  const record = [];
2159
- if (!checks.owner) record.push("choose an owner");
2160
- if (!checks.scope) record.push("select the Systems this covers");
2161
- if (!checks.operationPattern) record.push("set when it runs");
2162
- if (!checks.procedure) record.push("write who does what and when in Procedure");
2163
- if (!checks.evidenceSource) record.push("link the tool or system that can show it happened");
2159
+ if (!checks.owner) record.push("assign the actual owner from existing People or Appointments");
2160
+ if (!checks.scope) record.push("link the in-scope Systems already in the Program");
2161
+ if (!checks.operationPattern) record.push("record whether it runs continuously, per transaction, on a schedule, or after an event");
2162
+ if (!checks.procedure) record.push("write the current actors, configuration, and procedure in Record Markdown");
2163
+ if (!checks.evidenceSource) record.push("link the authoritative Component that can produce proof");
2164
2164
  if (!checks.policyMapping && checks.policyMapping !== undefined) record.push("link the Policy it implements");
2165
2165
  if (!checks.criteriaMapping && checks.criteriaMapping !== undefined) record.push("link the criteria it covers");
2166
- if (!checks.implementationDate) record.push("record the actual date it starts working when marking Implemented");
2166
+ if (!checks.implementationDate) record.push("record the date the working implementation took effect when marking Implemented");
2167
2167
  if (checks.procedureRevision === false || checks.procedureEffective === false) {
2168
2168
  record.push("record the Procedure revision and effective date");
2169
2169
  }
@@ -2174,16 +2174,16 @@ export function controlImplementationSteps(control, checks, options = {}) {
2174
2174
  ? `Cover the missing evidence families: ${sourceTargets.length ? sourceTargets.join(" and ") : "this Control"}. For each, link an active Component with the matching kind, evidence owners, and report retrieval instructions.`
2175
2175
  : null;
2176
2176
  const queueStep = checks.workQueue === false
2177
- ? "Check the linked Obligations. Enable one with the owner and schedule for this Control's recurring or event work, or add one if none covers it."
2177
+ ? "Inspect linked Obligations and their Policy basis. Enable a suitable existing rule with its owner and deadline, or add a rule only if no existing one covers this work. A scheduled rule does not prove a cycle occurred."
2178
2178
  : null;
2179
2179
  if (!checks.implemented) {
2180
2180
  if (sourceStep || queueStep) steps.push([sourceStep, queueStep].filter(Boolean).join(" "));
2181
- else if (checks.applicability === false) steps.push("Confirm this Control applies to the current Program scope with `review-applicability --scaffold --type control`.");
2182
- else steps.push("When these launch conditions hold, mark the Control Implemented. This asserts the practice works now; record proof from future cycles and events as they occur.");
2181
+ else if (checks.applicability === false) steps.push("Compare this Control with the current Program scope and record its applicability decision with `review-applicability --scaffold --type control`; ask management only if the decision cannot be established from the scope and commitments.");
2182
+ else steps.push("When these launch conditions hold, mark the Control Implemented with its real effective date. Record dated proof later, when a cycle or event actually occurs.");
2183
2183
  } else {
2184
2184
  if (sourceStep) steps.push(sourceStep);
2185
2185
  if (queueStep) steps.push(queueStep);
2186
- if (checks.applicability === false) steps.push("Confirm this Control applies to the current Program scope with `review-applicability --scaffold --type control`.");
2186
+ if (checks.applicability === false) steps.push("Compare this Control with the current Program scope and record its applicability decision with `review-applicability --scaffold --type control`; ask management only if the decision cannot be established from the scope and commitments.");
2187
2187
  }
2188
2188
  return steps;
2189
2189
  }
package/src/web.js CHANGED
@@ -1231,7 +1231,7 @@ function controlLaunchLabel(state) {
1231
1231
  return ({
1232
1232
  planned: "Planned: launch conditions remain",
1233
1233
  partial: "Partially implemented: launch conditions remain",
1234
- "ready-to-implement": "Launch checks ready: confirm it works, then record the start date",
1234
+ "ready-to-implement": "Launch checks ready: check the live configuration, then record its start date",
1235
1235
  "implemented-with-gaps": "Implemented with gaps: fix the launch checks",
1236
1236
  implemented: "Implemented"
1237
1237
  })[state] || "Control launch";
package/src/workflow.js CHANGED
@@ -466,13 +466,17 @@ function recordIncompleteReason(record, loaded, program) {
466
466
  return {
467
467
  state: "ready",
468
468
  requiredness: appointmentRequiredness(record, loaded.model),
469
- message: "Assign a holder, confirm the authority and independence needed, then activate this Appointment on its actual start date."
469
+ message: "Check current People and scoped Appointments, assign a qualified holder, and record the actual authority and start date. Ask management only if the holder or independence decision is unresolved."
470
470
  };
471
471
  }
472
472
  const messages = {
473
473
  draft: "Add the required details, relationships, and Markdown before review.",
474
474
  planned: "Check this planned record against how your program works, then add the missing details.",
475
- proposed: "Confirm the work, owner, schedule, and completion requirements before activation.",
475
+ proposed: ["obligation", "obligation-rule"].includes(record.type)
476
+ ? "Read the linked Policy and Control, fill the actual owner, schedule, deadline, and proof requirement, then activate the rule. Ask management only for a choice those sources do not settle."
477
+ : record.type === "reporting-route-set"
478
+ ? "Fill the normal and fallback reporting routes from approved contact details, commit the proposal, and obtain the required separate approval before it takes effect. Ask only for missing route or authority decisions."
479
+ : "Inspect the source facts and type guide, complete the proposal, and obtain the required review or approval before activation.",
476
480
  "in-review": "Have an independent reviewer approve the exact content revision.",
477
481
  open: "Complete this work with the required proof, or formally close it without completion.",
478
482
  "in-progress": "Finish the work, record the result, and link the completion proof.",
@@ -724,7 +728,7 @@ function reconciliationFindings(reconciliation) {
724
728
  state: "ready",
725
729
  severity: "warning",
726
730
  requiredness: "conditional",
727
- title: `Confirm ${fieldLabel(candidate.eventType)}`,
731
+ title: `Resolve ${fieldLabel(candidate.eventType)} transition`,
728
732
  message: candidate.message,
729
733
  subject: candidate.subject,
730
734
  fieldPath: candidate.sourcePath,
@@ -1630,12 +1634,12 @@ function periodFinding(key, title, message, state, subject, actions, dependencie
1630
1634
  function auditClosureNextStep(status) {
1631
1635
  const steps = {
1632
1636
  planned: {
1633
- title: "Confirm the engagement and start audit preparation",
1634
- message: "Link the agreed engagement terms, confirm scope and management acknowledgement, then move the audit to in progress."
1637
+ title: "Record the agreed engagement and start audit preparation",
1638
+ message: "Read the signed engagement terms, link them, record the agreed scope and management acknowledgement, then move the audit to in progress. Ask for missing terms or acknowledgement only if unavailable."
1635
1639
  },
1636
1640
  "in-progress": {
1637
1641
  title: "Begin fieldwork",
1638
- message: "Finish management preparation, confirm the fieldwork dates, and move the audit to fieldwork when the CPA firm begins testing."
1642
+ message: "Finish management preparation, record the fieldwork dates agreed with the CPA firm, and move the audit to fieldwork when testing begins. Ask for the dates only if they are not in the engagement correspondence."
1639
1643
  },
1640
1644
  fieldwork: {
1641
1645
  title: "Finish fieldwork and prepare the report",
@@ -1647,7 +1651,7 @@ function auditClosureNextStep(status) {
1647
1651
  },
1648
1652
  issued: {
1649
1653
  title: "Record final report delivery",
1650
- message: "Confirm the issued report evidence, opinion, report date, authorized recipient, and delivery receipt, then move the audit to delivered."
1654
+ message: "Read the issued report and delivery record, enter the opinion, report date, authorized recipient, and receipt, then move the audit to delivered. Ask only for missing delivery facts."
1651
1655
  },
1652
1656
  delivered: {
1653
1657
  title: "Close the audit",