open-agreements 0.2.0 → 0.2.2

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 (66) hide show
  1. package/README.md +10 -2
  2. package/content/templates/closing-checklist/metadata.yaml +6 -13
  3. package/content/templates/closing-checklist/template.docx +0 -0
  4. package/dist/cli/index.d.ts.map +1 -1
  5. package/dist/cli/index.js +47 -10
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/commands/checklist.d.ts +21 -1
  8. package/dist/commands/checklist.d.ts.map +1 -1
  9. package/dist/commands/checklist.js +175 -44
  10. package/dist/commands/checklist.js.map +1 -1
  11. package/dist/commands/recipe.js +3 -11
  12. package/dist/commands/recipe.js.map +1 -1
  13. package/dist/core/checklist/index.d.ts +22 -14
  14. package/dist/core/checklist/index.d.ts.map +1 -1
  15. package/dist/core/checklist/index.js +79 -39
  16. package/dist/core/checklist/index.js.map +1 -1
  17. package/dist/core/checklist/jsonl-stores.d.ts +3 -0
  18. package/dist/core/checklist/jsonl-stores.d.ts.map +1 -0
  19. package/dist/core/checklist/jsonl-stores.js +16 -0
  20. package/dist/core/checklist/jsonl-stores.js.map +1 -0
  21. package/dist/core/checklist/schemas.d.ts +2 -2
  22. package/dist/core/checklist/schemas.js +1 -1
  23. package/dist/core/checklist/schemas.js.map +1 -1
  24. package/dist/core/checklist/state-manager.d.ts +146 -0
  25. package/dist/core/checklist/state-manager.d.ts.map +1 -0
  26. package/dist/core/checklist/state-manager.js +147 -0
  27. package/dist/core/checklist/state-manager.js.map +1 -0
  28. package/dist/core/checklist/status-labels.d.ts +6 -0
  29. package/dist/core/checklist/status-labels.d.ts.map +1 -0
  30. package/dist/core/checklist/status-labels.js +29 -0
  31. package/dist/core/checklist/status-labels.js.map +1 -0
  32. package/dist/core/validation/recipe.d.ts.map +1 -1
  33. package/dist/core/validation/recipe.js +47 -61
  34. package/dist/core/validation/recipe.js.map +1 -1
  35. package/package.json +1 -1
  36. package/skills/cloud-service-agreement/SKILL.md +9 -0
  37. package/skills/data-privacy-agreement/SKILL.md +9 -0
  38. package/skills/delaware-franchise-tax/SKILL.md +56 -19
  39. package/skills/delaware-franchise-tax/reference/ecorp-portal-playwright-notes.md +136 -0
  40. package/skills/edit-docx-agreement/CONNECTORS.md +20 -0
  41. package/skills/edit-docx-agreement/SKILL.md +77 -0
  42. package/skills/employment-contract/SKILL.md +9 -0
  43. package/skills/iso-27001-evidence-collection/CONNECTORS.md +23 -0
  44. package/skills/iso-27001-evidence-collection/SKILL.md +300 -0
  45. package/skills/iso-27001-evidence-collection/rules/api-exports.md +191 -0
  46. package/skills/iso-27001-evidence-collection/rules/evidence-types.md +107 -0
  47. package/skills/iso-27001-evidence-collection/rules/screenshot-guide.md +77 -0
  48. package/skills/iso-27001-internal-audit/CONNECTORS.md +23 -0
  49. package/skills/iso-27001-internal-audit/SKILL.md +272 -0
  50. package/skills/iso-27001-internal-audit/rules/access-control.md +191 -0
  51. package/skills/iso-27001-internal-audit/rules/business-continuity.md +94 -0
  52. package/skills/iso-27001-internal-audit/rules/change-management.md +211 -0
  53. package/skills/iso-27001-internal-audit/rules/encryption.md +93 -0
  54. package/skills/iso-27001-internal-audit/rules/incident-response.md +127 -0
  55. package/skills/iso-27001-internal-audit/rules/isms-management.md +164 -0
  56. package/skills/iso-27001-internal-audit/rules/logging-monitoring.md +96 -0
  57. package/skills/iso-27001-internal-audit/rules/people-controls.md +161 -0
  58. package/skills/iso-27001-internal-audit/rules/supplier-management.md +92 -0
  59. package/skills/nda/SKILL.md +9 -0
  60. package/skills/open-agreements/SKILL.md +9 -0
  61. package/skills/safe/SKILL.md +9 -0
  62. package/skills/services-agreement/SKILL.md +9 -0
  63. package/skills/soc2-readiness/CONNECTORS.md +23 -0
  64. package/skills/soc2-readiness/SKILL.md +289 -0
  65. package/skills/soc2-readiness/rules/trust-services.md +230 -0
  66. package/skills/venture-financing/SKILL.md +9 -0
@@ -0,0 +1,136 @@
1
+ # Delaware eCorp Portal — Playwright Automation Notes
2
+
3
+ ## Setup
4
+
5
+ ### Launch Chrome with remote debugging
6
+
7
+ ```bash
8
+ # Must quit Chrome first, then relaunch with debug port
9
+ osascript -e 'tell application "Google Chrome" to quit'
10
+ sleep 2
11
+ /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
12
+ --remote-debugging-port=9222 \
13
+ --user-data-dir=/tmp/chrome-debug-profile &
14
+ ```
15
+
16
+ ### Connect via Playwright (CDP)
17
+
18
+ ```python
19
+ NODE_OPTIONS='--no-deprecation' uv run python3 << 'PYEOF'
20
+ from playwright.sync_api import sync_playwright
21
+ with sync_playwright() as p:
22
+ browser = p.chromium.connect_over_cdp("http://localhost:9222")
23
+ ctx = browser.contexts[0]
24
+ page = ctx.pages[0]
25
+ PYEOF
26
+ ```
27
+
28
+ ## Fixes & Gotchas
29
+
30
+ ### 1. Readonly "Total Issued Shares" field
31
+ - `gridStock_ctl02_txtIssuedShares` is **readonly** — it's auto-summed from per-class fields
32
+ - Fill the per-class field instead: `gridStock_ctl02_gridStockDetails_ctl02_txtIssuedShares`
33
+ - This populates the readonly total automatically on recalculate
34
+
35
+ ### 2. Asset Date field mangles input with Playwright .fill()/.type()
36
+ - The date field has a mask/formatter that garbles Playwright keyboard input
37
+ - **Fix**: Use JavaScript to set the value directly:
38
+ ```python
39
+ page.evaluate('''
40
+ const el = document.getElementById('ctl00_ContentPlaceHolder1_gridStock_ctl02_txtAssetDate');
41
+ el.value = '12/31/2025';
42
+ el.dispatchEvent(new Event('change', { bubbles: true }));
43
+ ''')
44
+ ```
45
+ - The portal requires asset date == fiscal year end date, or it ignores gross assets
46
+
47
+ ### 3. APVC method activation
48
+ - Portal defaults to Authorized Shares method ($85,165 for 10M shares)
49
+ - To get APVC: fill issued shares + gross assets + correct asset date, then click "Recalculate Tax"
50
+ - If asset date doesn't match fiscal year end, recalculate silently stays on Authorized Shares
51
+
52
+ ### 4. ASP.NET ViewState breaks on back-navigation
53
+ - Never use `page.go_back()` — the ViewState expires and you get a server error
54
+ - Always start fresh from the login page: `https://icis.corp.delaware.gov/ecorp/logintax.aspx`
55
+
56
+ ### 5. Postback links (2024 "File Amended Annual Report")
57
+ - The link is `javascript:__doPostBack(...)`, not a real URL
58
+ - Can't open in a new tab via href — must execute on the page
59
+ - Use: `page.evaluate("__doPostBack('ctl00$ContentPlaceHolder1$lnkPrevAR','')")`
60
+
61
+ ### 6. CAPTCHA
62
+ - Field: `#ctl00_ContentPlaceHolder1_ecorpCaptcha1_txtCaptcha`
63
+ - Image: `#ctl00_ContentPlaceHolder1_ecorpCaptcha1_captchaImage` (NOT `img[src*='Captcha']`)
64
+ - Case-insensitive in practice (all caps in image)
65
+ - Screenshot cropping can be unreliable — fetch the CAPTCHA image bytes via JS `fetch()` on `img.src` as fallback
66
+
67
+ ### 7. Key field selectors
68
+ | Field | Selector ID (after ctl00_ContentPlaceHolder1_) |
69
+ |-------|------------------------------------------------|
70
+ | File number | txtPrimaryFileNo |
71
+ | CAPTCHA | ecorpCaptcha1_txtCaptcha |
72
+ | Continue button | btnContinue |
73
+ | Issued shares (per-class) | gridStock_ctl02_gridStockDetails_ctl02_txtIssuedShares |
74
+ | Issued shares (total, readonly) | gridStock_ctl02_txtIssuedShares |
75
+ | Gross assets | gridStock_ctl02_txtGrossAsset |
76
+ | Asset date | gridStock_ctl02_txtAssetDate |
77
+ | Fiscal year end | txtFiscalYearEndYear |
78
+ | Recalculate button | btnRecalucation (note: typo in portal) |
79
+ | Continue Filing button | btnProceedPayment |
80
+ | Enter Directors button | btnDisplayDirectorForm |
81
+ | Nature of Business | ddlBusinessNatures |
82
+
83
+ ### 8. State dropdowns use abbreviations (NY, WA, etc.)
84
+ - All state dropdowns (`drpHidePrincipal`, `drpHideOfficer`, `drpHideAuthor`, `drpDirectorStatesN`) use 2-letter state codes
85
+ - Use `page.select_option("#drpHidePrincipal", value="NY")` — NOT `label="New York"`
86
+
87
+ ### 9. Director form fields (inline, not popup)
88
+ - Click `#btnDisplayDirectorForm` to reveal director rows
89
+ - **CRITICAL**: Director names have THREE separate fields per director:
90
+ - `txtDirectorName{N}` = **first name only** (NOT full name!)
91
+ - `txtMiddleName{N}` = middle name/initial
92
+ - `txtLastName{N}` = last name (REQUIRED — validation fails without it)
93
+ - Other fields: `txtDirectorAddress{N}`, `txtDirectorCity{N}`, `drpDirectorStates{N}`, `txtDirectorZip{N}`, `drpDirectorCountry{N}`
94
+ - Numbered 1–N based on `txtTotalNumOfDirectors`
95
+ - All use simple IDs (no ASP.NET prefix)
96
+
97
+ ### 10. Tax result label IDs (different from what you'd expect)
98
+ | Label | Selector ID (after ctl00_ContentPlaceHolder1_) |
99
+ |-------|------------------------------------------------|
100
+ | Franchise Tax | lblFranchisetaxData |
101
+ | Penalty | lblPenaltyData |
102
+ | Interest | lblMonthlyIntrestData |
103
+ | Filing Fee | lblAnnualFilingDta |
104
+ | Credit | lblPreviousData |
105
+ | Prepaid | lblPrepaidPaymentData |
106
+ | **Total Due** | **lblAmountDue** |
107
+
108
+ ### 11. Officer and Authorization address fields
109
+ | Section | Street | City | State | Zip |
110
+ |---------|--------|------|-------|-----|
111
+ | Principal | txtStreetPrincipal | txtCityPrincipal | drpHidePrincipal | txtZipPrincipal |
112
+ | Officer | txtStreetOfficer | txtCityOfficer | drpHideOfficer | txtZipOfficer |
113
+ | Auth | txtStreetAuthorization | txtCityAuthorization | drpHideAuthor | txtZipAuthorization |
114
+
115
+ ### 12. Session/eId behavior
116
+ - Dashboard URL needs `eId` parameter from login — can't bookmark dashboard directly
117
+ - **BUT**: Cmd+Back (browser history) in a new tab CAN get back to dashboard within the same session
118
+ - Each login generates a unique eId; session cookies are shared across tabs
119
+
120
+ ### 13. T&C checkbox required before Continue Filing
121
+ - Must check `#ctl00_ContentPlaceHolder1_chkCertify` before clicking Continue Filing
122
+ - Validation error: "Authorization: Please check the box to confirm that you have read the Terms and Conditions"
123
+
124
+ ### 14. Confirmation page — save BEFORE navigating away
125
+ - **"Once you leave this screen, you will no longer be able to obtain a confirmation copy"**
126
+ - **PDF download**: `downloadConfirmation()` → opens `DownLoadConfirmation.ashx?srNo=...&fileNo=...`
127
+ - Triggers a file download, NOT a page navigation — Playwright will throw "Download is starting" error (that's OK, the file downloads)
128
+ - **Email confirmation**: `openARemail()` → opens `Email.aspx?srNo=...` popup
129
+ - Fill `#txtEmailAddress` and `#txtVerifyEmailAddress`, click `#btnEmail`
130
+ - Response: "Your e-mail request has been received. Please allow 48 hours."
131
+ - Service Request Number is in the URL: `?srNo=XXXXXXXXXXX`
132
+
133
+ ### 15. Deprecation warning
134
+ - `[DEP0169] url.parse() behavior is not standardized` comes from Playwright's Node.js internals
135
+ - Harmless — Playwright uses `url.parse()` in its server; fix is upstream (Playwright issue)
136
+ - Suppress with: `NODE_OPTIONS='--no-deprecation'` env var
@@ -0,0 +1,20 @@
1
+ # Connectors
2
+
3
+ ## OpenAgreements (for template filling)
4
+
5
+ Use the standard OpenAgreements connectors (remote MCP or local CLI) for fill operations.
6
+ See https://github.com/open-agreements/open-agreements/blob/main/skills/open-agreements/CONNECTORS.md for details.
7
+
8
+ ## Safe Docx MCP (for surgical DOCX editing)
9
+
10
+ Safe Docx is a **separate MCP server** that must be configured independently.
11
+ It is not part of the OpenAgreements skill set.
12
+
13
+ The user must have Safe Docx MCP already set up in their agent environment.
14
+ If Safe Docx tools are not available, instruct the user to:
15
+
16
+ 1. Visit https://github.com/UseJunior/safe-docx for setup instructions
17
+ 2. Configure the Safe Docx MCP server in their agent's MCP settings
18
+ 3. Restart their agent session
19
+
20
+ Do not instruct the agent to download or install packages at runtime.
@@ -0,0 +1,77 @@
1
+ ---
2
+ name: edit-docx-agreement
3
+ description: >-
4
+ Make bespoke edits to a DOCX agreement generated by OpenAgreements (or any existing DOCX),
5
+ using Safe Docx MCP tools for surgical, formatting-preserving edits and tracked-changes outputs.
6
+ license: MIT
7
+ compatibility: >-
8
+ Works with any agent. Requires a separately configured Safe Docx MCP server for document editing.
9
+ OpenAgreements fill capabilities require the OpenAgreements remote MCP or local CLI.
10
+ metadata:
11
+ author: open-agreements
12
+ version: "0.2.0"
13
+ ---
14
+
15
+ # edit-docx-agreement
16
+
17
+ Use this skill when a user asks for **custom edits that are not exposed as template fields** in an OpenAgreements-generated (or any existing) DOCX agreement.
18
+
19
+ > **Interactivity note**: Always ask the user for missing inputs (file path, change intent, output preferences).
20
+
21
+ ## Security model
22
+
23
+ This skill bridges two separate systems:
24
+ - **OpenAgreements** (remote MCP or local CLI) — for template filling. Follows the OpenAgreements zero-download security model.
25
+ - **Safe Docx** (local MCP server) — for surgical DOCX editing. Requires separate setup. This is **not** part of the OpenAgreements skill set and has its own trust/security model.
26
+
27
+ The agent must have Safe Docx MCP tools available to perform edits. If Safe Docx tools are not detected, inform the user and provide setup guidance (see Connectors).
28
+
29
+ ## Decision rule: refill vs edit vs both
30
+
31
+ 1. **Field-only changes** (e.g., party name, date, amount, valuation cap):
32
+ Re-run OpenAgreements `fill_template` with the updated field values. No Safe Docx needed.
33
+
34
+ 2. **Boilerplate-only changes** (e.g., custom clause, modified standard language):
35
+ Use Safe Docx MCP tools to surgically edit the existing DOCX.
36
+
37
+ 3. **Mixed changes** (field updates + bespoke edits):
38
+ Re-fill via OpenAgreements first (to get a clean base with updated fields), save the output locally, then use Safe Docx to apply bespoke edits on the fresh file.
39
+
40
+ ## Execution
41
+
42
+ ### Step 0: Confirm you have a local .docx file path
43
+
44
+ - If OpenAgreements was run via remote MCP, the fill response returns a download URL (with `expires_at`). Save the DOCX to a local path immediately.
45
+ - If the download link has expired, re-run `fill_template` to get a fresh URL.
46
+ - If OpenAgreements was run via local CLI, use the output file path directly.
47
+
48
+ ### Step 1: Verify Safe Docx MCP is available
49
+
50
+ Check whether Safe Docx tools (e.g., `read_file`, `replace_text`, `apply_plan`) are available in the current session.
51
+
52
+ - **If available**: proceed to Step 2.
53
+ - **If not available**: inform the user that Safe Docx MCP is required for bespoke edits and provide setup instructions from the Connectors file. Stop here until the user configures it.
54
+
55
+ ### Step 2: Apply the decision rule
56
+
57
+ Follow the routing logic above (field-only / boilerplate-only / mixed).
58
+
59
+ For Safe Docx edits:
60
+ - Use `read_file` to locate target paragraphs
61
+ - Use `replace_text` or `insert_paragraph` for surgical changes
62
+ - Use `apply_plan` for batch edits (fails safely if any step is invalid)
63
+ - Re-read edited paragraphs to verify changes
64
+
65
+ ### Step 3: Deliver reviewable outputs
66
+
67
+ Use Safe Docx `download` to save:
68
+ - A **tracked-changes** DOCX for legal review
69
+ - A **clean** DOCX for signing (optional but recommended)
70
+
71
+ Summarize edits for the user (paragraph IDs, before/after text).
72
+
73
+ ## Licensing note
74
+
75
+ Some templates (notably YC SAFEs) are licensed under CC-BY-ND-4.0. You can fill them for your own use but must not redistribute modified versions of the template itself. The filled output may constitute an "adapted work" — do not redistribute your filled output publicly without reviewing the license terms. See `docs/licensing.md` for details.
76
+
77
+ This tool does not provide legal advice — consult an attorney.
@@ -155,3 +155,12 @@ Use `list_templates` (MCP) or `list --json` (CLI) for the latest inventory and f
155
155
  - OpenAgreements employment templates are licensed under CC-BY-4.0
156
156
  - These templates are designed for US at-will employment — state-specific laws may apply
157
157
  - This tool does not provide legal advice — consult an attorney
158
+
159
+ ## Bespoke edits (beyond template fields)
160
+
161
+ If you need to edit boilerplate or add custom language that is not exposed as a template field,
162
+ use the `edit-docx-agreement` skill to surgically edit the generated DOCX and produce a
163
+ tracked-changes output for review. This requires a separately configured Safe Docx MCP server.
164
+
165
+ Note: templates licensed under CC-BY-ND-4.0 (e.g., YC SAFEs) can be filled for your own use
166
+ but must not be redistributed in modified form.
@@ -0,0 +1,23 @@
1
+ # Connectors
2
+
3
+ ## How tool references work
4
+
5
+ This skill uses `~~category` placeholders for optional integrations. The skill works without any connectors configured — they enhance the experience when available.
6
+
7
+ ## Connectors for this skill
8
+
9
+ | Category | Placeholder | Recommended server | Other options |
10
+ |----------|-------------|-------------------|---------------|
11
+ | Compliance data | `~~compliance` | Compliance MCP server (planned — not yet available) | Local `compliance/` directory files |
12
+
13
+ ### Local compliance data (current default)
14
+
15
+ If the `compliance/` directory exists with evidence status files, the skill reads those directly. No MCP server needed — just ensure evidence files in `compliance/evidence/*.md` are up to date.
16
+
17
+ ### Compliance MCP server (planned)
18
+
19
+ A dedicated compliance MCP server with automated gap detection and evidence freshness tracking is planned but not yet available. When released, it will be installable as a standard MCP server. Until then, the skill operates in local-data or reference-only mode.
20
+
21
+ ### Fallback: Reference only
22
+
23
+ Without any connector, the skill uses embedded checklists and CLI command reference. No organization-specific evidence status is available in this mode.
@@ -0,0 +1,300 @@
1
+ ---
2
+ name: iso-27001-evidence-collection
3
+ description: >-
4
+ Collect, organize, and validate evidence for ISO 27001 and SOC 2 audits.
5
+ API-first approach with CLI commands for major cloud platforms. Produces
6
+ timestamped, auditor-ready evidence packages.
7
+ license: MIT
8
+ compatibility: >-
9
+ Works with any AI agent. Enhanced with compliance MCP server for automated
10
+ gap detection. Falls back to embedded checklists when no live data available.
11
+ metadata:
12
+ author: open-agreements
13
+ version: "0.1.0"
14
+ frameworks:
15
+ - ISO 27001:2022
16
+ - SOC 2 Type II
17
+ - NIST SP 800-53 Rev 5
18
+ ---
19
+
20
+ # ISO 27001 Evidence Collection
21
+
22
+ Systematically collect audit evidence for ISO 27001:2022 and SOC 2. This skill provides API-first evidence collection commands, organizes evidence by control, and validates completeness before auditor review.
23
+
24
+ ## Security Model
25
+
26
+ - **No scripts executed** — this skill is markdown-only procedural guidance
27
+ - **No secrets required** — works with reference checklists; CLI commands use existing local credentials
28
+ - **Evidence stays local** — all outputs go to the local filesystem
29
+ - **IP-clean** — references NIST SP 800-53 (public domain); ISO controls cited by section ID only
30
+
31
+ ## When to Use
32
+
33
+ Activate this skill when:
34
+
35
+ 1. **Preparing evidence package for external audit** — 2-4 weeks before auditor arrives
36
+ 2. **Quarterly evidence refresh** — update evidence that has aged beyond the audit window
37
+ 3. **After remediation** — collect evidence proving a finding has been fixed
38
+ 4. **New system onboarding** — establish baseline evidence for a newly in-scope system
39
+ 5. **Evidence gap analysis** — identify what's missing before the audit
40
+
41
+ Do NOT use for:
42
+ - Running the internal audit itself — use `iso-27001-internal-audit`
43
+ - SOC 2-only readiness assessment — use `soc2-readiness`
44
+ - Interpreting audit findings — use the internal audit skill
45
+
46
+ ## Core Concepts
47
+
48
+ ### Evidence Hierarchy (Best to Worst)
49
+
50
+ | Rank | Type | Example | Why Better |
51
+ |------|------|---------|------------|
52
+ | 1 | **API export (JSON/CSV)** | `gcloud iam service-accounts list --format=json` | Timestamped, tamper-evident, reproducible |
53
+ | 2 | **System-generated report** | SOC 2 report from vendor, SIEM export | Authoritative source, includes metadata |
54
+ | 3 | **Configuration export** | Terraform state, policy JSON | Shows intended state, version-controlled |
55
+ | 4 | **Screenshot with system clock** | `screencapture -x ~/evidence/...` | Visual proof, but harder to validate |
56
+ | 5 | **Manual attestation** | Signed statement by responsible person | Last resort, requires corroboration |
57
+
58
+ ### Evidence Freshness Requirements
59
+
60
+ | Evidence Type | Max Age | Refresh Cadence |
61
+ |---------------|---------|-----------------|
62
+ | Access lists | 90 days | Quarterly |
63
+ | Vulnerability scans | 30 days | Monthly |
64
+ | Configuration exports | 90 days | Quarterly |
65
+ | Training records | 12 months | Annual |
66
+ | Penetration test | 12 months | Annual |
67
+ | Policy documents | 12 months | Annual review |
68
+ | Incident records | Audit period | Continuous |
69
+ | Risk assessment | 12 months | Annual + on change |
70
+
71
+ ### Evidence Naming Convention
72
+
73
+ ```
74
+ {control_id}_{evidence_type}_{YYYY-MM-DD}.{ext}
75
+ ```
76
+
77
+ Examples:
78
+ - `A.5.15_user-access-list_2026-02-28.json`
79
+ - `A.8.8_vulnerability-scan_2026-02-28.csv`
80
+ - `A.8.13_backup-test-results_2026-02-28.pdf`
81
+
82
+ ## Step-by-Step Workflow
83
+
84
+ ### Step 1: Identify Evidence Gaps
85
+
86
+ Determine what evidence is missing or stale.
87
+
88
+ ```
89
+ # If compliance MCP is available:
90
+ list_evidence_gaps(framework="iso27001_2022", tier="critical")
91
+
92
+ # If reading local compliance data:
93
+ # Check compliance/evidence/*.md files for upload_status != "OK"
94
+ # Check renewal_next dates for upcoming expirations
95
+ ```
96
+
97
+ ### Step 2: Prioritize Collection
98
+
99
+ Order evidence collection by:
100
+ 1. **Missing evidence for Critical-tier controls** — audit blockers
101
+ 2. **Stale evidence past renewal date** — auditor will reject
102
+ 3. **Evidence for Relevant-tier controls** — expected but not blocking
103
+ 4. **Checkbox-tier evidence** — policies and attestations
104
+
105
+ ### Step 3: Collect by Platform
106
+
107
+ Run evidence collection commands grouped by platform to minimize context-switching.
108
+
109
+ #### GitHub Evidence
110
+ ```bash
111
+ # Org settings: MFA requirement, default permissions
112
+ gh api orgs/{org} | jq '{
113
+ two_factor_requirement_enabled,
114
+ default_repository_permission,
115
+ members_can_create_public_repositories
116
+ }' > evidence/A.5.17_github-org-mfa_$(date +%Y-%m-%d).json
117
+
118
+ # Branch protection on production repos
119
+ for repo in $(gh repo list {org} --json name -q '.[].name'); do
120
+ gh api repos/{org}/$repo/branches/main/protection 2>/dev/null | \
121
+ jq '{repo: "'$repo'", protection: .}' >> evidence/A.8.32_branch-protection_$(date +%Y-%m-%d).json
122
+ done
123
+
124
+ # Recent merged PRs (change management evidence)
125
+ gh pr list --state merged --limit 50 --json number,title,author,reviewDecision,mergedAt,mergedBy \
126
+ > evidence/A.8.32_change-records_$(date +%Y-%m-%d).json
127
+
128
+ # Dependabot alerts (vulnerability management)
129
+ gh api repos/{org}/{repo}/dependabot/alerts?state=open \
130
+ > evidence/A.8.8_dependabot-alerts_$(date +%Y-%m-%d).json
131
+
132
+ # Secret scanning alerts
133
+ gh api orgs/{org}/secret-scanning/alerts --paginate \
134
+ > evidence/A.8.24_secret-scanning_$(date +%Y-%m-%d).json
135
+
136
+ # Audit log
137
+ gh api orgs/{org}/audit-log?per_page=100 \
138
+ > evidence/A.8.15_github-audit-log_$(date +%Y-%m-%d).json
139
+ ```
140
+
141
+ #### GCP Evidence
142
+ ```bash
143
+ # IAM policy (access control)
144
+ gcloud projects get-iam-policy {project} --format=json \
145
+ > evidence/A.5.15_gcp-iam-policy_$(date +%Y-%m-%d).json
146
+
147
+ # Service accounts
148
+ gcloud iam service-accounts list --format=json \
149
+ > evidence/A.5.16_gcp-service-accounts_$(date +%Y-%m-%d).json
150
+
151
+ # Audit logging config
152
+ gcloud projects get-iam-policy {project} --format=json | jq '.auditConfigs' \
153
+ > evidence/A.8.15_gcp-audit-config_$(date +%Y-%m-%d).json
154
+
155
+ # Log sinks (centralization)
156
+ gcloud logging sinks list --format=json \
157
+ > evidence/A.8.15_gcp-log-sinks_$(date +%Y-%m-%d).json
158
+
159
+ # Compute instances (asset inventory)
160
+ gcloud compute instances list --format=json \
161
+ > evidence/A.5.9_gcp-compute-inventory_$(date +%Y-%m-%d).json
162
+
163
+ # Cloud SQL backup config
164
+ gcloud sql backups list --instance={instance} --format=json \
165
+ > evidence/A.8.13_gcp-sql-backups_$(date +%Y-%m-%d).json
166
+
167
+ # Firewall rules
168
+ gcloud compute firewall-rules list --format=json \
169
+ > evidence/A.8.20_gcp-firewall-rules_$(date +%Y-%m-%d).json
170
+ ```
171
+
172
+ #### Azure Evidence
173
+ ```bash
174
+ # Role assignments (access control)
175
+ az role assignment list --all --output json \
176
+ > evidence/A.5.15_azure-role-assignments_$(date +%Y-%m-%d).json
177
+
178
+ # Activity log (audit trail)
179
+ az monitor activity-log list --max-events 100 --output json \
180
+ > evidence/A.8.15_azure-activity-log_$(date +%Y-%m-%d).json
181
+
182
+ # Network security groups
183
+ az network nsg list --output json \
184
+ > evidence/A.8.20_azure-nsgs_$(date +%Y-%m-%d).json
185
+
186
+ # Backup jobs
187
+ az backup job list --resource-group {rg} --vault-name {vault} --output json \
188
+ > evidence/A.8.13_azure-backup-jobs_$(date +%Y-%m-%d).json
189
+
190
+ # Storage encryption
191
+ az storage account list --query "[].{name:name, encryption:encryption}" --output json \
192
+ > evidence/A.8.24_azure-storage-encryption_$(date +%Y-%m-%d).json
193
+ ```
194
+
195
+ #### Google Workspace Evidence
196
+ ```bash
197
+ # User list with MFA status
198
+ gam print users fields primaryEmail,name,isEnrolledIn2Sv,isEnforcedIn2Sv,lastLoginTime,suspended \
199
+ > evidence/A.5.17_workspace-users-mfa_$(date +%Y-%m-%d).csv
200
+
201
+ # Admin roles
202
+ gam print admins > evidence/A.8.2_workspace-admins_$(date +%Y-%m-%d).csv
203
+
204
+ # Mobile devices
205
+ gam print mobile > evidence/A.8.1_workspace-mobile-devices_$(date +%Y-%m-%d).csv
206
+ ```
207
+
208
+ #### macOS Endpoint Evidence
209
+ ```bash
210
+ # FileVault encryption
211
+ fdesetup status > evidence/A.8.24_filevault-status_$(date +%Y-%m-%d).txt
212
+
213
+ # System configuration
214
+ system_profiler SPHardwareDataType SPSoftwareDataType \
215
+ > evidence/A.8.1_endpoint-config_$(date +%Y-%m-%d).txt
216
+
217
+ # Screen lock settings
218
+ profiles show -type configuration 2>/dev/null | grep -A10 -i "lock\|idle\|screensaver" \
219
+ > evidence/A.6.7_screenlock-config_$(date +%Y-%m-%d).txt
220
+ ```
221
+
222
+ ### Step 4: Validate Evidence Package
223
+
224
+ Check completeness before submitting to auditor:
225
+
226
+ 1. **Completeness**: Do you have evidence for every applicable control in the SoA?
227
+ 2. **Freshness**: Is every piece of evidence within the required age?
228
+ 3. **Format**: Are API exports in JSON/CSV with timestamps? Screenshots have system clock visible?
229
+ 4. **Naming**: Files follow the naming convention?
230
+ 5. **Coverage**: Critical-tier controls have at least 2 forms of evidence?
231
+
232
+ ```
233
+ # If compliance MCP is available:
234
+ list_evidence_gaps(framework="iso27001_2022") # Should return empty for complete package
235
+ ```
236
+
237
+ ### Step 5: Generate Evidence Index
238
+
239
+ Create an index file listing all evidence, mapped to controls:
240
+
241
+ ```markdown
242
+ # Evidence Package Index
243
+ Generated: {date}
244
+ Audit period: {start} to {end}
245
+
246
+ | Control | Evidence File | Type | Collected | Status |
247
+ |---------|--------------|------|-----------|--------|
248
+ | A.5.15 | gcp-iam-policy_2026-02-28.json | API export | 2026-02-28 | Current |
249
+ | A.5.17 | workspace-users-mfa_2026-02-28.csv | API export | 2026-02-28 | Current |
250
+ | ... | ... | ... | ... | ... |
251
+ ```
252
+
253
+ ## DO / DON'T
254
+
255
+ ### DO
256
+ - Use API exports with ISO 8601 timestamps over screenshots whenever possible
257
+ - Collect evidence from the SOURCE system (IdP, not a secondary report)
258
+ - Include metadata: collection date, system version, user who collected
259
+ - Store evidence in version-controlled directory with clear naming
260
+ - Collect evidence for the AUDIT PERIOD (usually past 12 months), not just current state
261
+ - Use `screencapture -x ~/evidence/{filename}.png` for screenshots (captures without shadow/border)
262
+
263
+ ### DON'T
264
+ - Take screenshots without visible system clock (menu bar on macOS, taskbar on Windows)
265
+ - Collect evidence from sandbox/staging instead of production
266
+ - Manually edit evidence after collection (auditors may verify against source)
267
+ - Wait until the week before the audit to collect everything
268
+ - Assume stale evidence is acceptable — check freshness requirements above
269
+ - Mix evidence from different audit periods in the same file
270
+
271
+ ## Troubleshooting
272
+
273
+ | Problem | Solution |
274
+ |---------|----------|
275
+ | API command requires auth | Use existing local credentials: `gcloud auth login`, `az login`, `gh auth login` |
276
+ | Tool not installed | Install: `brew install gh`, `brew install --cask google-cloud-sdk`, `brew install azure-cli` |
277
+ | Insufficient permissions | Request read-only access to the relevant service; document the access request as evidence |
278
+ | Evidence too large | Use `--limit` or `--max-events` flags; collect summary statistics instead of full export |
279
+ | Vendor won't provide SOC 2 report | Request via their trust center; if unavailable, document the request and use their security page |
280
+ | Screenshot doesn't include clock | On macOS: use full-screen capture, or `screencapture -x` which includes menu bar |
281
+
282
+ ## Rules
283
+
284
+ For detailed evidence collection guidance by topic:
285
+
286
+ | File | Coverage |
287
+ |------|----------|
288
+ | `rules/api-exports.md` | CLI commands by cloud provider (GCP, Azure, AWS, GitHub, Google Workspace) |
289
+ | `rules/screenshot-guide.md` | When and how to take audit-ready screenshots |
290
+ | `rules/evidence-types.md` | Evidence type requirements per control domain |
291
+
292
+ ## Attribution
293
+
294
+ Evidence collection procedures and control guidance developed with [Internal ISO Audit](https://internalisoaudit.com) (Hazel Castro, ISO 27001 Lead Auditor, 14+ years, 100+ audits).
295
+
296
+ ## Runtime Detection
297
+
298
+ 1. **Compliance MCP server available** (best) — Automated gap detection, evidence freshness tracking
299
+ 2. **Local compliance data available** (good) — Reads evidence status from `compliance/evidence/*.md`
300
+ 3. **Reference only** (baseline) — Uses embedded checklists and command reference