一键导入
summarize-v3
Produce final APPROVAL-REPORT.md with framework coverage matrix, mitigation traceability, control inventory, test evidence, and verdict
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Produce final APPROVAL-REPORT.md with framework coverage matrix, mitigation traceability, control inventory, test evidence, and verdict
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Run a 5-domain CAF security posture assessment for an AWS service. Produces (1) assessment-summary.md — CAF-structured findings with GAPS tables, (2) sar-facts.json — extracted SAR data, (3) checkpoint-results.json — factual checkpoint verification. These feed into the research, validate, and generate phases.
Run live AWS CLI probes against deployed compliant resources to prove each mapped control is enforced. Produces control x CLI x verdict matrix. Phase 7 of the pipeline.
Generate detective and responsive security control artifacts — Config rules with Lambda handlers, EventBridge rules, CloudWatch alarms, SSM runbooks, Step Functions workflows, CloudTrail configuration. Reads from mapping-results.json and validated.json.
Generate compliant IaC templates in all 4 formats — modular Terraform, CDK TypeScript, CloudFormation YAML, and CDK for Terraform. Uses parameter coverage matrix from mapping-results.json and API surface from validated.json.
Generate preventive and proactive security control artifacts — SCPs, resource policies, KMS key policies, permission boundaries, tag policies, OPA policies, and CloudFormation Guard rules. Reads from mapping-results.json and validated.json.
Generate all security control artifacts and compliant IaC templates from mapping-results.json and validated.json. Split into 3 focused sub-skills for better accuracy; this skill orchestrates them.
| name | summarize-v3 |
| description | Produce final APPROVAL-REPORT.md with framework coverage matrix, mitigation traceability, control inventory, test evidence, and verdict |
| disable-model-invocation | false |
Read all state files and generate the final approval report at .service-approval/<slug>/07-summarize/APPROVAL-REPORT.md.
python3 -m tools.validate.check_phase_complete --slug <slug> --phase 01-assess || exit 2
python3 -m tools.validate.check_phase_complete --slug <slug> --phase 03-validate || exit 2
python3 -m tools.validate.check_phase_complete --slug <slug> --phase 04-map || exit 2
test -d .service-approval/<slug>/05-generate || { echo "ERROR: run generator first"; exit 2; }
Phase 6 (Test) is OPTIONAL — proceed even if 06-test/ is absent (mark test
as NOT RUN in the report). The summarize skill must NOT pre-gate Phase 6
because intake's testing.mode=skip is a legitimate path that skips Phase 5.Read validated.json for unverified_count. Read test-results.json if it exists.
| Condition | Verdict |
|---|---|
test_results.passed = true AND unverified_count = 0 | APPROVED |
test_results.passed = true AND unverified_count > 0 | APPROVED WITH EXCEPTIONS |
test_results.skipped = true AND unverified_count = 0 | APPROVED (test not run) |
test_results.passed = false | REQUIRES REMEDIATION |
test-results.json absent | APPROVED (test not run) |
Note: passed: null (dry-run) is treated the same as skipped: true.
Read mapping-results.json framework_mapping[]. Build a table:
| {Framework} Objective ID | Title | Domain | Satisfied By | Coverage |
Where "Satisfied By" = comma-separated control IDs that map to this framework objective.
Use the framework name dynamically from mapping-results.json.framework.name.
Read mapping-results.json threat_mitigation_map[]. Build a table:
| Mitigation ID | Statement | Resource Type | Controls | Framework Objectives | Coverage |
Where "Statement" = statement field.
Where "Controls" = control_ids[] from the mitigation entry (joined, comma-separated).
Where "Framework Objectives" = framework_objectives[] from the mitigation entry. If this field
is absent, derive it: for each control id in the mitigation's control_ids[], look up that control
in the top-level controls[] and collect its framework_objectives[]. Deduplicate and sort.
This shows end-to-end traceability from customer mitigations through controls to framework objectives.
For each file in .service-approval/<slug>/05-generate/, read its _metadata or header comments
(lines starting with # SCOPE:, # LAYER:, # CONTROLS:, # FRAMEWORK:).
Build a table per layer: | Layer | Scope | Artifact | Controls | Framework Objectives |
find .service-approval/<slug>/05-generate -type f | sort
CRITICAL — Terminology rules for the report: The APPROVAL-REPORT.md is a customer-facing document. NEVER use internal/pipeline terms:
Write .service-approval/<slug>/07-summarize/APPROVAL-REPORT.md with these sections.
Section headings are H2 (##) — the report's top-level title # Service Approval Report — {Service} is H1, so all section headers under it are H2. Downstream
consumers (skills/evidence/SKILL.md awk extraction, validate_pipeline_integrity.py
P6 verdict-consistency check) anchor on H2; writing H3 here silently breaks both.
[Verdict string with date, service name, resource count]
[Coverage numbers: N controls generated, N framework objectives covered, N mitigations addressed, test result]
Include this section only if assessment-summary.md exists.
assessment_gap_ids[])[Full table from Step 2 — all framework objectives, mapped or N/A]
Use the framework name dynamically from mapping-results.json.framework.name:
--framework=nist only): "NIST 800-53 Coverage Matrix"--framework=cis only): "CIS Benchmarks Coverage Matrix"--framework=iso only): "ISO 27001 Coverage Matrix"Note: as of 2026-05-16, interactive runs are narrowed to CCMv4 by intake. The non-CCMv4 branches above are reachable only when an advanced operator bypasses intake with
--framework=<type>.
[Full table from Step 3 — all customer mitigations with control and framework mappings] Include coverage summary: N/N mitigations fully covered, N partially covered, N uncovered.
Include this section only if mapping-results.json contains attack_coverage.
This section renders threat model coverage regardless of which threat model was used as input
(MITRE ATT&CK, custom STRIDE model, organizational threat catalog, etc.). The section title
and content adapt based on the attack_coverage data:
attack_coverage.attack_matrix_version for the threat model versionattack_coverage.attack_matrix_source for the source file name (if present)Section title: Use the threat model name dynamically (mirrors the 5-case
naming-rules table in skills/research-attack-surface/SKILL.md):
data/attack-cloud-matrix.json) → "MITRE ATT&CK Threat Coverage (v{version})"Build a tactic/category heat map showing control coverage:
| Tactic / Category | Techniques | Covered | Coverage |
|-------------------|-----------|---------|----------|
| Initial Access (TA0001) | 3 | 2 | ██████░░ 67% |
| Execution (TA0002) | 2 | 2 | ████████ 100% |
| Persistence (TA0003) | 3 | 1 | ██░░░░░░ 33% |
[repeat for each tactic/category with applicable techniques]
Include a "Threat Gaps" sub-section listing uncovered HIGH-applicability techniques/threats:
If customer_stride_profile exists in research-attack-surface.json, also include a
STRIDE coverage summary showing which STRIDE categories have controls addressing them:
| STRIDE Category | Mitigations Referenced | Techniques Mapped | Controls Covering |
|-----------------|----------------------|-------------------|-------------------|
| Spoofing | M-AgentRuntime.0, ... | T1078.004, T1199 | CTRL-005, CTRL-006 |
[repeat for each STRIDE category]
[Per-layer table from Step 4, organized by Controls Matrix cell]
[Config rule finding count, Config compliance status, mitigation coverage %, framework coverage % — or "Test not run" if skipped]
[List with reasons, or "None — all items verified" if unverified_count = 0]
[Full file list from Step 5]
NEW: If .service-approval/<slug>/08-evidence/ exists, append this section:
Runtime validation complete. Phase 7 Evidence runner executed CLI probes against deployed resources to verify each control is enforced. See:
08-evidence/attestation-report.md — control x CLI x verdict matrix08-evidence/attestation-results.json — machine-readable verdicts08-evidence/summary.md — top-level triage digestEvidence coverage: {pass_count} / {total_controls} controls verified PASS, {not_cli_validatable_count} NOT_CLI_VALIDATABLE.
Otherwise, omit this section (Evidence phase was not run).
Deployment order:
05-generate/iac/Render this section only when intake-manifest.json.testing.mode == "manual-cli".
The user opted out of automated Phase 5 testing and asked for per-format deploy
commands. Inspect .service-approval/<slug>/05-generate/iac/ and emit only the commands that
match formats actually present. Always use placeholders (<STACK_NAME>,
<AWS_PROFILE>, <AWS_REGION>) — never substitute a real profile name.
python3 - <<'PY'
import json
from pathlib import Path
manifest = Path(f".service-approval/{slug}/00-intake/intake-manifest.json")
if not manifest.exists():
raise SystemExit(0)
mode = json.loads(manifest.read_text()).get("testing", {}).get("mode")
if mode != "manual-cli":
raise SystemExit(0)
iac = Path(f".service-approval/{slug}/05-generate/iac")
has_cfn = any(iac.glob("*.cfn.yaml")) or any(iac.glob("*.yaml"))
has_terraform = (iac / "modules").exists()
has_cdk = any(iac.rglob("*.ts")) and not (iac / "cdktf").exists()
has_cdktf = (iac / "cdktf").exists() or any(iac.rglob("cdktf.json"))
blocks = []
if has_cfn:
blocks.append(f"""**CloudFormation:**
```bash
aws cloudformation deploy \\
--template-file .service-approval/{slug}/05-generate/iac/compliant-resource.cfn.yaml \\
--stack-name <STACK_NAME> \\
--capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM \\
--profile <AWS_PROFILE>
```""")
if has_terraform:
blocks.append(f"""**Terraform:**
```bash
cd .service-approval/{slug}/05-generate/iac
terraform init
terraform plan -out tfplan
terraform apply tfplan
```""")
if has_cdk:
blocks.append(f"""**CDK TypeScript:**
```bash
cd .service-approval/{slug}/05-generate/iac
npm install
npx cdk bootstrap --profile <AWS_PROFILE>
npx cdk deploy --profile <AWS_PROFILE>
```""")
if has_cdktf:
blocks.append(f"""**CDK for Terraform:**
```bash
cd .service-approval/{slug}/05-generate/iac/cdktf
npm install
npx cdktf deploy
```""")
if (Path(f".service-approval/{slug}/05-generate/responsive/lambda-remediator/template.yaml")).exists():
blocks.append(f"""**Detective controls stack (deploy after compliant resource):**
```bash
aws cloudformation deploy \\
--template-file .service-approval/{slug}/05-generate/responsive/lambda-remediator/template.yaml \\
--stack-name <STACK_NAME>-detective \\
--capabilities CAPABILITY_IAM \\
--profile <AWS_PROFILE>
```""")
print("\n\n".join(blocks) if blocks else "No deployable IaC artifacts found.")
PY
Append the rendered blocks to APPROVAL-REPORT.md under this heading. Skip the
entire section when testing.mode is anything other than manual-cli.
After APPROVAL-REPORT.md is written, emit a terminal-state sentinel to
pipeline.log. This signals to the Stop hook (validate_pipeline_integrity.py
P1 check) that the run is finalized — the file is frozen, and remediation-only
checks like the MCP-call-count gate cannot be retroactively satisfied.
Without this sentinel, the Stop hook re-fires forever on completed runs that
happen to have a P1 violation in their pipeline.log.
Emit AFTER the report file is closed and AFTER the print summary, only when
Phase 7 Evidence is NOT in scope (Evidence's Step 11 owns the sentinel when
it runs). Detect Phase 7-in-scope by intake-manifest.json.testing.mode == "full-deploy".
# Map verdict to sentinel form. Drop any parenthesized qualifier first so
# "APPROVED (test not run)" canonicalizes to "APPROVED" (the qualifier is
# audit-trail metadata, not a distinct verdict — see "Sentinel canonicalization"
# note below). Then uppercase and fold spaces/hyphens to underscores.
VERDICT_TAG=$(echo "<verdict>" \
| sed -E 's/ *\(.*\)$//' \
| tr '[:lower:]' '[:upper:]' | tr ' -' '__')
# e.g., "APPROVED with exceptions" -> "APPROVED_WITH_EXCEPTIONS"
# e.g., "APPROVED (test not run)" -> "APPROVED"
python3 -m tools.validate.log \
--slug <slug> \
--phase 07-summarize \
--source pipeline:complete \
--verdict "${VERDICT_TAG}" \
--message "summarize finalized; verdict=${VERDICT_TAG}"
Sentinel canonicalization: the validator's closed allowlist is
APPROVED | APPROVED_WITH_EXCEPTIONS | REQUIRES_REMEDIATION. Parenthesized
qualifiers in the verdict table (e.g., APPROVED (test not run)) are
informational metadata, not distinct verdicts — they describe which
subset of validation ran, not whether the run was approved. The sentinel
canonicalizes them away so the gate stays binary; consumers needing the
original qualifier read APPROVAL-REPORT.md directly, not the sentinel
token. Adding new parenthesized variants does NOT require validator
allowlist changes; adding a new bare verdict (e.g., a hypothetical
PENDING) does.
The validator anchors on the literal token [pipeline:complete:<VERDICT>],
where <VERDICT> is uppercase letters with underscores. Mid-flight runs
without the sentinel still get the strict P1 check.
Print:
Report written: .service-approval/<slug>/07-summarize/APPROVAL-REPORT.md
Verdict: <APPROVED|APPROVED WITH EXCEPTIONS|REQUIRES REMEDIATION>
Framework: {name} — {mapped} / {total} objectives covered
Mitigations: {covered} / {total} addressed
Threat model: {threat_model_name} — {covered} / {total} techniques covered (if attack_coverage present)
Total control artifacts: N