@intentsolutionsio/penetration-tester 2.0.0 → 3.0.4

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 (112) hide show
  1. package/.claude-plugin/plugin.json +8 -3
  2. package/README.md +8 -0
  3. package/commands/pentest.md +5 -0
  4. package/package.json +8 -3
  5. package/skills/analyzing-tls-config/SKILL.md +221 -0
  6. package/skills/analyzing-tls-config/references/AUTHORIZATION.md +133 -0
  7. package/skills/analyzing-tls-config/references/PLAYBOOK.md +267 -0
  8. package/skills/analyzing-tls-config/references/THEORY.md +128 -0
  9. package/skills/analyzing-tls-config/scripts/analyze_tls.py +415 -0
  10. package/skills/auditing-cors-policy/SKILL.md +186 -0
  11. package/skills/auditing-cors-policy/references/PLAYBOOK.md +220 -0
  12. package/skills/auditing-cors-policy/references/THEORY.md +142 -0
  13. package/skills/auditing-cors-policy/scripts/audit_cors.py +350 -0
  14. package/skills/auditing-npm-dependencies/SKILL.md +254 -0
  15. package/skills/auditing-npm-dependencies/references/PLAYBOOK.md +175 -0
  16. package/skills/auditing-npm-dependencies/references/THEORY.md +122 -0
  17. package/skills/auditing-npm-dependencies/scripts/audit_npm.py +408 -0
  18. package/skills/auditing-python-dependencies/SKILL.md +251 -0
  19. package/skills/auditing-python-dependencies/references/PLAYBOOK.md +193 -0
  20. package/skills/auditing-python-dependencies/references/THEORY.md +122 -0
  21. package/skills/auditing-python-dependencies/scripts/audit_python.py +459 -0
  22. package/skills/checking-http-security-headers/SKILL.md +176 -0
  23. package/skills/checking-http-security-headers/references/PLAYBOOK.md +212 -0
  24. package/skills/checking-http-security-headers/references/THEORY.md +137 -0
  25. package/skills/checking-http-security-headers/scripts/check_headers.py +362 -0
  26. package/skills/checking-license-compliance/SKILL.md +225 -0
  27. package/skills/checking-license-compliance/references/PLAYBOOK.md +161 -0
  28. package/skills/checking-license-compliance/references/THEORY.md +152 -0
  29. package/skills/checking-license-compliance/scripts/check_licenses.py +461 -0
  30. package/skills/composing-vulnerability-report/SKILL.md +212 -0
  31. package/skills/composing-vulnerability-report/references/PLAYBOOK.md +180 -0
  32. package/skills/composing-vulnerability-report/references/THEORY.md +178 -0
  33. package/skills/composing-vulnerability-report/scripts/compose_report.py +396 -0
  34. package/skills/confirming-pentest-authorization/SKILL.md +247 -0
  35. package/skills/confirming-pentest-authorization/references/PLAYBOOK.md +189 -0
  36. package/skills/confirming-pentest-authorization/references/THEORY.md +167 -0
  37. package/skills/confirming-pentest-authorization/scripts/check_authorization.py +457 -0
  38. package/skills/defining-pentest-scope/SKILL.md +227 -0
  39. package/skills/defining-pentest-scope/references/PLAYBOOK.md +238 -0
  40. package/skills/defining-pentest-scope/references/THEORY.md +170 -0
  41. package/skills/defining-pentest-scope/scripts/define_scope.py +472 -0
  42. package/skills/detecting-command-injection-patterns/SKILL.md +144 -0
  43. package/skills/detecting-command-injection-patterns/references/PLAYBOOK.md +302 -0
  44. package/skills/detecting-command-injection-patterns/references/THEORY.md +206 -0
  45. package/skills/detecting-command-injection-patterns/scripts/scan_cmdi.py +290 -0
  46. package/skills/detecting-debug-endpoints/SKILL.md +207 -0
  47. package/skills/detecting-debug-endpoints/references/PLAYBOOK.md +402 -0
  48. package/skills/detecting-debug-endpoints/references/THEORY.md +218 -0
  49. package/skills/detecting-debug-endpoints/scripts/probe_debug.py +518 -0
  50. package/skills/detecting-directory-listing/SKILL.md +206 -0
  51. package/skills/detecting-directory-listing/references/PLAYBOOK.md +277 -0
  52. package/skills/detecting-directory-listing/references/THEORY.md +203 -0
  53. package/skills/detecting-directory-listing/scripts/probe_directory_listing.py +180 -0
  54. package/skills/detecting-eval-exec-usage/SKILL.md +128 -0
  55. package/skills/detecting-eval-exec-usage/references/PLAYBOOK.md +306 -0
  56. package/skills/detecting-eval-exec-usage/references/THEORY.md +159 -0
  57. package/skills/detecting-eval-exec-usage/scripts/scan_eval.py +223 -0
  58. package/skills/detecting-exposed-secrets-files/SKILL.md +179 -0
  59. package/skills/detecting-exposed-secrets-files/references/PLAYBOOK.md +274 -0
  60. package/skills/detecting-exposed-secrets-files/references/THEORY.md +174 -0
  61. package/skills/detecting-exposed-secrets-files/scripts/probe_secrets.py +207 -0
  62. package/skills/detecting-insecure-deserialization/SKILL.md +148 -0
  63. package/skills/detecting-insecure-deserialization/references/PLAYBOOK.md +333 -0
  64. package/skills/detecting-insecure-deserialization/references/THEORY.md +199 -0
  65. package/skills/detecting-insecure-deserialization/scripts/scan_deserialization.py +250 -0
  66. package/skills/detecting-sql-injection-patterns/SKILL.md +161 -0
  67. package/skills/detecting-sql-injection-patterns/references/PLAYBOOK.md +317 -0
  68. package/skills/detecting-sql-injection-patterns/references/THEORY.md +261 -0
  69. package/skills/detecting-sql-injection-patterns/scripts/scan_sqli.py +354 -0
  70. package/skills/detecting-ssl-cert-issues/SKILL.md +182 -0
  71. package/skills/detecting-ssl-cert-issues/references/PLAYBOOK.md +203 -0
  72. package/skills/detecting-ssl-cert-issues/references/THEORY.md +133 -0
  73. package/skills/detecting-ssl-cert-issues/scripts/check_cert_chain.py +481 -0
  74. package/skills/detecting-weak-cryptography/SKILL.md +147 -0
  75. package/skills/detecting-weak-cryptography/references/PLAYBOOK.md +466 -0
  76. package/skills/detecting-weak-cryptography/references/THEORY.md +194 -0
  77. package/skills/detecting-weak-cryptography/scripts/scan_weak_crypto.py +417 -0
  78. package/skills/fingerprinting-server-software/SKILL.md +191 -0
  79. package/skills/fingerprinting-server-software/references/PLAYBOOK.md +337 -0
  80. package/skills/fingerprinting-server-software/references/THEORY.md +183 -0
  81. package/skills/fingerprinting-server-software/scripts/fingerprint_server.py +347 -0
  82. package/skills/generating-executive-summary/SKILL.md +261 -0
  83. package/skills/generating-executive-summary/references/PLAYBOOK.md +201 -0
  84. package/skills/generating-executive-summary/references/THEORY.md +195 -0
  85. package/skills/generating-executive-summary/scripts/exec_summary.py +538 -0
  86. package/skills/mapping-findings-to-owasp-top10/SKILL.md +235 -0
  87. package/skills/mapping-findings-to-owasp-top10/references/PLAYBOOK.md +193 -0
  88. package/skills/mapping-findings-to-owasp-top10/references/THEORY.md +160 -0
  89. package/skills/mapping-findings-to-owasp-top10/scripts/map_owasp.py +540 -0
  90. package/skills/performing-penetration-testing/SKILL.md +282 -190
  91. package/skills/performing-penetration-testing/references/OWASP_TOP_10.md +22 -0
  92. package/skills/performing-penetration-testing/references/REMEDIATION_PLAYBOOK.md +46 -0
  93. package/skills/performing-penetration-testing/references/SECURITY_HEADERS.md +41 -0
  94. package/skills/performing-penetration-testing/scripts/code_security_scanner.py +144 -79
  95. package/skills/performing-penetration-testing/scripts/dependency_auditor.py +116 -93
  96. package/skills/performing-penetration-testing/scripts/security_scanner.py +574 -446
  97. package/skills/probing-dangerous-http-methods/SKILL.md +182 -0
  98. package/skills/probing-dangerous-http-methods/references/PLAYBOOK.md +234 -0
  99. package/skills/probing-dangerous-http-methods/references/THEORY.md +145 -0
  100. package/skills/probing-dangerous-http-methods/scripts/probe_methods.py +263 -0
  101. package/skills/recording-pentest-engagement/SKILL.md +253 -0
  102. package/skills/recording-pentest-engagement/references/PLAYBOOK.md +203 -0
  103. package/skills/recording-pentest-engagement/references/THEORY.md +195 -0
  104. package/skills/recording-pentest-engagement/scripts/record_engagement.py +461 -0
  105. package/skills/scanning-for-hardcoded-secrets/SKILL.md +215 -0
  106. package/skills/scanning-for-hardcoded-secrets/references/PLAYBOOK.md +325 -0
  107. package/skills/scanning-for-hardcoded-secrets/references/THEORY.md +175 -0
  108. package/skills/scanning-for-hardcoded-secrets/scripts/scan_secrets.py +395 -0
  109. package/skills/tracing-transitive-vulnerabilities/SKILL.md +235 -0
  110. package/skills/tracing-transitive-vulnerabilities/references/PLAYBOOK.md +233 -0
  111. package/skills/tracing-transitive-vulnerabilities/references/THEORY.md +138 -0
  112. package/skills/tracing-transitive-vulnerabilities/scripts/trace_vulns.py +484 -0
@@ -0,0 +1,189 @@
1
+ # PLAYBOOK — ROE Templates and Authorization Flow
2
+
3
+ ## Default ROE template
4
+
5
+ ```yaml
6
+ engagement_id: <CLIENT>-<YEAR>-<QUARTER>-PENTEST-<NN>
7
+ authorizer:
8
+ name: ""
9
+ email: ""
10
+ role: "" # CISO, CTO, VP Eng, Director of Security, etc.
11
+ organization: ""
12
+ in_scope_targets:
13
+ - host: ""
14
+ notes: ""
15
+ out_of_scope_targets:
16
+ - host: ""
17
+ reason: ""
18
+ time_window:
19
+ start: "2026-MM-DDT00:00:00Z"
20
+ end: "2026-MM-DDT23:59:59Z"
21
+ emergency_contact:
22
+ name: ""
23
+ phone: ""
24
+ email: ""
25
+ rules:
26
+ - No exploitation of confirmed findings without written prompt approval.
27
+ - No password cracking against production accounts.
28
+ - Testing pauses during declared business-hours blackout windows.
29
+ - All findings are confidential until report delivery.
30
+ signature_block:
31
+ signer: ""
32
+ signed_at: "2026-MM-DDTHH:MM:SSZ"
33
+ signature: |
34
+ <PGP signature, DocuSign envelope ID, or equivalent attestation>
35
+ ```
36
+
37
+ ## Per-engagement-type variants
38
+
39
+ ### External web-app pentest
40
+
41
+ `in_scope_targets` is hosts/URLs. `rules` typically include "no
42
+ DoS, no brute-force against rate-limited endpoints, no testing
43
+ during peak hours (specify the window)."
44
+
45
+ ### Internal network pentest
46
+
47
+ `in_scope_targets` is CIDRs. `out_of_scope_targets` typically
48
+ excludes the company VOIP range, the surveillance camera VLAN,
49
+ and any PCI scope without separate authz. `rules` typically include
50
+ "no exploit of the domain controller, no lateral movement past
51
+ the documented hop limit."
52
+
53
+ ### Red-team engagement
54
+
55
+ `in_scope_targets` may be the entire ASN, with explicit `out_of_scope`
56
+ exclusions. `rules` typically include "exfiltration attempts are
57
+ in scope; persistence mechanisms must be reversible; physical
58
+ intrusion is/isn't included." Time window is often months.
59
+
60
+ ### Purple-team engagement
61
+
62
+ ROE has an explicit clause acknowledging the SOC is informed.
63
+ Adds a `coordination_contact` field for the SOC liaison.
64
+
65
+ ### Cloud account pentest (AWS/Azure/GCP)
66
+
67
+ `in_scope_targets` includes account IDs / subscription IDs.
68
+ `rules` typically include "no creation of new principal
69
+ identities beyond the documented test identity; no modification
70
+ of production IAM roles."
71
+
72
+ ### SaaS integration pentest
73
+
74
+ `in_scope_targets` is the customer's tenant in the SaaS app.
75
+ `rules` typically include the SaaS vendor's own policy
76
+ (many SaaS vendors require explicit prior notification before
77
+ testing).
78
+
79
+ ## Authorization escalation flow
80
+
81
+ When the prospective authorizer says "yes, you can test," the
82
+ escalation flow inside the customer's organization typically:
83
+
84
+ 1. **Operational owner agreement** — the team that owns the
85
+ system signs off that testing is welcome.
86
+ 2. **Security leadership approval** — CISO or equivalent
87
+ approves the engagement scope.
88
+ 3. **Legal review** — the customer's counsel reviews the ROE
89
+ for indemnification, liability cap, and scope clarity.
90
+ 4. **Executive sign-off** — for high-value or high-risk
91
+ engagements, CFO/COO/CEO sign as the binding party.
92
+
93
+ The skill's `.allowed-authorizers` list captures step 2 + 4
94
+ identities — security leadership + executive sign-off — as the
95
+ authoritative signers. Operational owners are not in the
96
+ allowlist by default because they typically don't bind the
97
+ organization legally.
98
+
99
+ ## Time-window extension procedure
100
+
101
+ When an in-progress engagement needs more time:
102
+
103
+ 1. Tester requests extension via the engagement's documented
104
+ communication channel.
105
+ 2. Authorizer (or delegate from the allowlist) signs a new ROE
106
+ with the extended `time_window.end`.
107
+ 3. Tester archives BOTH the original ROE and the extension; the
108
+ skill is re-run against the extension and produces a fresh
109
+ authorization record.
110
+
111
+ Never run the skill on a ROE whose time window has been verbally
112
+ or informally extended. The whole point of the schema is to make
113
+ extensions auditable.
114
+
115
+ ## Emergency-stop protocol
116
+
117
+ A pentest can need to stop immediately when:
118
+
119
+ - The customer's SOC detects testing activity and treats it as a
120
+ real attack (the test pre-notification didn't reach the SOC
121
+ team on shift).
122
+ - An out-of-scope system is accidentally probed.
123
+ - The tester's tools cause an unexpected outage.
124
+ - The customer requests a halt for any reason.
125
+
126
+ The ROE's `emergency_contact` field is the call-immediately
127
+ number. Halting is a hard stop:
128
+
129
+ 1. Cease all active tools.
130
+ 2. Notify the emergency_contact verbally.
131
+ 3. Document the stop time + reason.
132
+ 4. Re-run the authorization skill before resuming. If anything
133
+ in the ROE changed (e.g. scope amendment), the skill produces
134
+ the new authorization record.
135
+
136
+ ## Allowed-authorizers file format
137
+
138
+ ```
139
+ # .allowed-authorizers — one signer identity per line
140
+ # Comments OK. Email addresses or PGP key fingerprints.
141
+
142
+ jane.doe@acme.example
143
+ john.smith@acme.example
144
+ 0xDEADBEEFCAFE1234
145
+ ```
146
+
147
+ Maintained by the tester's business-development team. Updates
148
+ should require a co-sign from a second person to prevent
149
+ single-actor manipulation.
150
+
151
+ ## Storage and retention
152
+
153
+ The ROE itself is part of the engagement evidence chain. Store
154
+ it in the engagement's evidence directory, NOT in the customer's
155
+ codebase under test:
156
+
157
+ ```
158
+ engagements/
159
+ └── acme-2026-q2/
160
+ ├── roe.yaml
161
+ ├── allowed-authorizers
162
+ ├── evidence/
163
+ │ ├── authz-check-20260601.json
164
+ │ ├── authz-check-20260615.json # after time-window extension
165
+ │ └── ...
166
+ └── findings/
167
+ └── ...
168
+ ```
169
+
170
+ Retention: keep ROEs for at least the statute-of-limitations
171
+ period for unauthorized-access offences in the relevant
172
+ jurisdiction (typically 5-7 years). Some customers require
173
+ longer retention for SOC2 / ISO 27001 evidence.
174
+
175
+ ## When the customer signs a "blanket" pentest authorization
176
+
177
+ Some customers issue a blanket annual or multi-year authorization
178
+ covering all engagements with a given pentester. This is legally
179
+ valid but operationally risky:
180
+
181
+ - Scope drift across engagements becomes invisible.
182
+ - Personnel changes on either side can void the blanket
183
+ implicitly.
184
+ - Time-window enforcement disappears.
185
+
186
+ Recommended: write a per-engagement ROE that references the
187
+ blanket authorization but adds specific scope + time window.
188
+ The blanket establishes the relationship; the per-engagement
189
+ ROE establishes what's authorized today.
@@ -0,0 +1,167 @@
1
+ # THEORY — Pentest Authorization as a Legal Primitive
2
+
3
+ ## The legal line
4
+
5
+ Computer-access laws across major jurisdictions criminalize
6
+ unauthorized access. The notable statutes:
7
+
8
+ | Jurisdiction | Statute | Key provision |
9
+ |---|---|---|
10
+ | United States | CFAA (18 USC §1030) | Accessing a protected computer "without authorization" or "exceeding authorized access" |
11
+ | United Kingdom | Computer Misuse Act 1990 | Unauthorized access (§1), unauthorized acts impairing computer operation (§3) |
12
+ | European Union | Directive 2013/40/EU | Illegal access, illegal system interference, illegal data interference |
13
+ | Singapore | Computer Misuse Act 1993 | Same shape; offence of unauthorized access |
14
+ | Australia | Criminal Code Act 1995 §477 | Unauthorized access, modification, or impairment |
15
+
16
+ The defining word in every statute is "authorization." A pentester
17
+ with explicit written authorization to access in-scope systems is
18
+ performing a legal security service. Without that authorization,
19
+ the same activity is a crime.
20
+
21
+ Authorization is not implicit. "I assumed they wanted me to test
22
+ their system" is not a defense. "They paid me to do security work"
23
+ is not sufficient if the system tested was outside the contracted
24
+ scope. The pentest industry has standardized the Rules of
25
+ Engagement (ROE) document as the artifact that establishes
26
+ authorization with the precision the law expects.
27
+
28
+ ## OSSTMM, PTES, and ROE history
29
+
30
+ Two open-source frameworks gave the industry its ROE template:
31
+
32
+ - **OSSTMM** (Open Source Security Testing Methodology Manual,
33
+ ISECOM, 2001 onward) — defined the scope-fingerprinting process
34
+ and what the engagement-letter checklist must cover.
35
+ - **PTES** (Penetration Testing Execution Standard, 2010 onward)
36
+ — formalized the pre-engagement phase, including ROE structure.
37
+
38
+ Both predate the cloud / API era and reflect a network-pentest
39
+ mental model. Modern engagements add fields for cloud accounts,
40
+ SaaS integrations, and ML-model probing that the original templates
41
+ don't anticipate. The schema this skill validates incorporates
42
+ common modern fields (SaaS scope, time windows, emergency contact)
43
+ on top of the OSSTMM/PTES foundation.
44
+
45
+ ## Signature options
46
+
47
+ The "signature" on a ROE is whatever evidence the authorizer's
48
+ counsel and your counsel agree establishes binding intent. Common
49
+ forms:
50
+
51
+ | Method | Strength | Effort |
52
+ |---|---|---|
53
+ | PGP / GPG signature on YAML/text ROE | Cryptographic; high | Moderate (both parties need GPG setup) |
54
+ | S/MIME signed PDF | Cryptographic; high | Moderate (certificate management) |
55
+ | DocuSign or HelloSign e-signature | Legally recognized in most jurisdictions; high | Low |
56
+ | Email with explicit "I authorize" statement, archived | Legally recognized but weaker (email impersonation risk) | Low |
57
+ | Wet-ink signature on printed ROE | Strongest in court; high | High (slow, physical) |
58
+ | Slack DM "yeah go ahead" | Often inadmissible; do NOT rely on | Trivial |
59
+
60
+ The skill validates the structural presence of a `signature_block`
61
+ in the ROE. Cryptographic verification (actually checking that a
62
+ PGP signature was made by the claimed key) is a separate step the
63
+ operator runs with `gpg --verify` before this skill runs. The
64
+ skill checks "is this ROE structurally signed?" not "is this
65
+ signature cryptographically valid?" — those are different gates,
66
+ and conflating them in one tool produces brittle failure modes.
67
+
68
+ ## Scope-creep failure modes
69
+
70
+ Engagements that go wrong tend to follow common patterns:
71
+
72
+ ### "Just one more system"
73
+
74
+ Tester finds an interesting adjacent system mid-engagement and
75
+ probes it. Adjacent system was NOT in the ROE. SOC team escalates.
76
+ Legal asks for the ROE. ROE doesn't cover the adjacent system.
77
+ Conversation gets expensive.
78
+
79
+ Mitigation: the skill's `--check-target` flag explicitly tests
80
+ whether a target is in scope BEFORE any probe runs. The
81
+ orchestrator should call it for every fresh target.
82
+
83
+ ### "I assumed prod was off-limits"
84
+
85
+ Tester avoids "obvious" production systems but probes systems
86
+ labeled "staging" that turn out to be production-attached.
87
+ Outage results.
88
+
89
+ Mitigation: ROE schema requires explicit `in_scope_targets` AND
90
+ `out_of_scope_targets`. The list of out-of-scope items is
91
+ prophylactic — if a target isn't on either list, the tester must
92
+ ask before proceeding.
93
+
94
+ ### "We extended verbally"
95
+
96
+ Engagement's time window expires, but the customer says verbally
97
+ "keep going for another week." Tester continues. Incident occurs.
98
+ ROE shows the time window as expired. The verbal extension is
99
+ unprovable.
100
+
101
+ Mitigation: time-window expiry is a CRITICAL finding in this
102
+ skill. The skill refuses to declare an engagement authorized if
103
+ the current time is outside the window, regardless of any other
104
+ field's state.
105
+
106
+ ### "The CISO's assistant said it was fine"
107
+
108
+ ROE was signed by someone whose authority over the systems was
109
+ unclear or absent. CISO denies authorizing.
110
+
111
+ Mitigation: the `.allowed-authorizers` file establishes which
112
+ signer identities are accepted. Maintained by the tester's
113
+ business-development team; new authorizers require vetting
114
+ before being added.
115
+
116
+ ## ROE template fields and why each matters
117
+
118
+ | Field | Why it's in the schema |
119
+ |---|---|
120
+ | `engagement_id` | Unambiguously identifies the engagement; lets multiple ROEs coexist without confusion |
121
+ | `authorizer.name + email + role` | Identifies who is authorizing; their role establishes that they have authority |
122
+ | `authorizer.organization` | Customer org; useful when the authorizer is a contractor or an MSP |
123
+ | `in_scope_targets` | The list. Without it, nothing is authorized |
124
+ | `out_of_scope_targets` | Prophylactic; clarifies known boundaries |
125
+ | `time_window.start + end` | Engagement is only authorized within this window |
126
+ | `emergency_contact` | Who to call if the test triggers an unexpected outage or law-enforcement contact |
127
+ | `rules` | Custom restrictions (no password spray on prod accounts, etc.) |
128
+ | `signature_block` | Establishes binding intent and which party is bound |
129
+ | `signature_block.signed_at` | When binding was established |
130
+
131
+ ## Why "halt on CRITICAL" is the right policy
132
+
133
+ The orchestrator routes to this skill FIRST and refuses to proceed
134
+ to cluster 1-4 skills if any CRITICAL finding emerges. The
135
+ rationale:
136
+
137
+ - A scan that produces findings against an unauthorized target
138
+ exposes the tester to legal liability.
139
+ - Even informational scans (port scans, DNS probes) against
140
+ unauthorized targets can constitute unauthorized access under
141
+ some statutes.
142
+ - The cost of halting is a delayed engagement. The cost of
143
+ proceeding without authorization is criminal exposure. The
144
+ asymmetry is severe; the discipline is the only constraint.
145
+
146
+ ## Cryptographic verification — out of scope here
147
+
148
+ PGP signature verification (does the signature on this ROE actually
149
+ match the public key of the claimed signer?) is performed by a
150
+ separate operator-run step:
151
+
152
+ ```bash
153
+ gpg --verify roe.yaml.asc roe.yaml
154
+ ```
155
+
156
+ The skill does not invoke GPG because:
157
+
158
+ 1. Many ROEs are signed via DocuSign or similar (no PGP at all).
159
+ 2. PGP key management is its own discipline — the skill would
160
+ become a key-management tool.
161
+ 3. Separating "structural presence of signature" from
162
+ "cryptographic validity of signature" makes failures easier
163
+ to diagnose.
164
+
165
+ A future enhancement could add `--verify-pgp` to bridge the two,
166
+ with explicit key-store configuration. For now, the skill checks
167
+ structure; the operator checks cryptography.