From de80ec3ee4f5fcef0ddc7db81b829f2e629b65b7 Mon Sep 17 00:00:00 2001 From: danny Date: Thu, 25 Dec 2025 09:11:43 +0000 Subject: [PATCH] InfraFabric Red Team header + inferred mermaid diagrams --- README.md | 4 +- docs/HANDOFF.md | 49 ++++++ .../AI-Code-Guardrails.shadow.dave.md | 128 +++++++++++++- src/revoice/generate.py | 159 +++++++++++++++++- src/revoice/lint.py | 15 +- style_bibles/IF.DAVE.BIBLE.md | 45 ++++- 6 files changed, 382 insertions(+), 18 deletions(-) create mode 100644 docs/HANDOFF.md diff --git a/README.md b/README.md index ad01c44..d3067b9 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Generate the Dave-style shadow dossier for the included PDF: ```bash PYTHONPATH=src python3 -m revoice generate \ - --style if.dave.v1.1 \ + --style if.dave.v1.2 \ --input examples/ai-code-guardrails/AI-Code-Guardrails.pdf \ --output examples/ai-code-guardrails/AI-Code-Guardrails.shadow.dave.md ``` @@ -22,7 +22,7 @@ Or install the CLI locally: ```bash python3 -m pip install -e . -revoice generate --style if.dave.v1 --input examples/ai-code-guardrails/AI-Code-Guardrails.pdf +revoice generate --style if.dave.v1.2 --input examples/ai-code-guardrails/AI-Code-Guardrails.pdf ``` ## What “apply a style bible” means diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md new file mode 100644 index 0000000..76ed04e --- /dev/null +++ b/docs/HANDOFF.md @@ -0,0 +1,49 @@ +# Handoff: re-voice (next agent) + +## What this repo is + +`re-voice` applies a versioned **style bible** to a source document to produce a **shadow dossier** (red-team lens + voice). + +Current focus style: +- Dave bible: `style_bibles/IF.DAVE.BIBLE.md` (`if://bible/dave/v1.2`) + +## Current behavior (v0.1) + +- Extraction: + - PDF: `pdftotext` fast-path, OCR fallback (`pdftoppm` → `tesseract`) + - MD/TXT: read as-is +- Generation (Dave v1.2): + - Section-by-section mirror for the Snyk PDF example using OCR section extraction + - Adds InfraFabric Red Team “declassified” header + inferred Mermaid diagrams + - Enforces “no new emojis unless in source” + +## How to run (example) + +```bash +PYTHONPATH=src python3 -m revoice generate \ + --style if.dave.v1.2 \ + --input examples/ai-code-guardrails/AI-Code-Guardrails.pdf \ + --output examples/ai-code-guardrails/AI-Code-Guardrails.shadow.dave.md + +PYTHONPATH=src python3 -m revoice lint \ + --style if.dave.v1.2 \ + --input examples/ai-code-guardrails/AI-Code-Guardrails.shadow.dave.md \ + --source examples/ai-code-guardrails/AI-Code-Guardrails.pdf +``` + +## Applying the stack to the full InfraFabric dossier + +Source (huge; ~1MB / ~22k lines): +- Repo view: `https://git.infrafabric.io/danny/Infrafabric-POC-docs/src/branch/main/DANNY_STOCKER_INFRAFABRIC_DOSSIER.md` +- Raw (best for tooling): `https://git.infrafabric.io/danny/Infrafabric-POC-docs/raw/branch/main/DANNY_STOCKER_INFRAFABRIC_DOSSIER.md` + +Recommended approach (don’t paste the whole file into chats): +- Use `rg '^## '` to enumerate major sections (the dossier is `##`-structured). +- Use `rg '^```mermaid'` to find existing diagrams (there are many). +- Apply Dave as a **sociotechnical red-team lens** in one of two modes: + 1) **Overlay mode (recommended for the dossier):** keep the original content, insert a short “Dave Factor” callout under each major `##` section describing dilution risks + the anti-Dave control (artifact/trace/owner/acceptance test). + 2) **Full rewrite mode (marketing/satire):** rewrite each major section into Dave-voice while mirroring headings; keep evidence/citations as “appendix artifacts” to avoid breaking auditability. + +Implementation note: +- To support the dossier properly, `revoice` should add a Markdown-aware section parser (split by headings, preserve code fences) and optionally an LLM-backed rewriter for “full rewrite mode.” + diff --git a/examples/ai-code-guardrails/AI-Code-Guardrails.shadow.dave.md b/examples/ai-code-guardrails/AI-Code-Guardrails.shadow.dave.md index 15b0c05..880e51b 100644 --- a/examples/ai-code-guardrails/AI-Code-Guardrails.shadow.dave.md +++ b/examples/ai-code-guardrails/AI-Code-Guardrails.shadow.dave.md @@ -1,10 +1,28 @@ -# AI CODE GUARDRAILS: -## A PRACTICAL GUIDE FOR SECURE ROLLOUT +--- +BRAND: InfraFabric.io +UNIT: RED TEAM (STRATEGIC OPS) +DOCUMENT: SHADOW DOSSIER +CLASSIFICATION: EYES ONLY // DAVE +--- + +# [ RED TEAM DECLASSIFIED ] +## PROJECT: AI-CODE-GUARDRAILS-MIRROR +### SOURCE: AI-CODE-GUARDRAILS-PDF +**INFRAFABRIC REPORT ID:** `IF-RT-DAVE-2025-1225` + +> NOTICE: This document is a product of InfraFabric Red Team. +> It provides socio-technical friction analysis for how a rollout survives contact with incentives. + +**[ ACCESS GRANTED: INFRAFABRIC RED TEAM ]** +**[ STATUS: OPERATIONAL REALISM ]** + +## AI CODE GUARDRAILS: +### A PRACTICAL GUIDE FOR SECURE ROLLOUT > Shadow dossier (mirror-first). > -> Protocol: IF.DAVE.v1.1 -> Citation: `if://bible/dave/v1.1` +> Protocol: IF.DAVE.v1.2 +> Citation: `if://bible/dave/v1.2` > Source: `examples/ai-code-guardrails/AI-Code-Guardrails.pdf` > Generated: `2025-12-25` > Source Hash (sha256): `6153a5998fe103e69f6d5b6042fbe780476ff869a625fcf497fd1948b2944b7c` @@ -25,6 +43,8 @@ The source frames the core tension clearly: higher throughput tends to surface m Accordingly, the practical path is to operationalize guardrails as workflow defaults (PR, IDE, CI/CD, and access controls), while ensuring the rollout remains optimized for alignment and minimal disruption on paper. In other words: we can move fast and be safe, as long as we define safe as "documented" and fast as "agendized." +> **InfraFabric Red Team Note:** Vendors sell secure speed. InfraFabric audits what survives contact with bureaucracy. + ## ENFORCE GUARDRAILS AT THE PULL REQUEST STAGE Why it matters: Pull requests are a natural place to catch AI-generated vulnerabilities before they reach production. @@ -33,6 +53,21 @@ We fully support focusing guardrails at the pull request stage, because it creat It also provides a structurally safe venue for accountability theater: findings can be surfaced, tracked, and re-litigated in perpetuity while timelines remain subject to stakeholder alignment. If anything goes sideways, we can always point to the PR thread and note that it was reviewed with deep seriousness at 4:55 PM on a Friday. +### InfraFabric Red Team Diagram (Inferred) + +```mermaid +flowchart TD + A[Code change] --> B[Pull request opened] + B --> C[Automated scan (PR checks)] + C --> D{Findings?} + D -->|None| E[Merge] + D -->|Some| F[Ticket created] + F --> G[Exception request] + G --> H[Alignment session] + H --> I[Risk accepted (documented)] + I --> E +``` + ## SHIFTING LEFT: AVOIDING AI- GENERATED CODE INEFFICIENCIES Why it matters: Catching security issues during development reduces rework and keeps developers focused on building, @@ -41,6 +76,20 @@ Shifting left is directionally aligned with best practices, provided we define l In practice, IDE scanning creates fast feedback loops, and agentic workflows can be covered via a local MCP server, which is excellent because it allows us to say continuous without committing to blocking. We recommend a pilot cohort, a slide deck, and an FAQ, so the shift remains culturally reversible. +### InfraFabric Red Team Diagram (Inferred) + +```mermaid +flowchart TD + A[Developer writes code] --> B[IDE scan (local)] + B --> C{Issue found?} + C -->|Yes| D[Fix now] + C -->|No| E[Commit] + E --> F[PR checks] + A --> G[Agent workflow] + G --> H[Local MCP scan] + H --> E +``` + ## 01 — REQUEST EVIDENCE OF LOCAL SECURITY TESTING Why it matters: Verifying security setup at the start encourages responsible tool use and builds good security @@ -49,6 +98,22 @@ Requiring proof of local testing is a lightweight enablement workflow that conve Screenshots are particularly helpful because they are high-effort to verify and low-fidelity to audit, which preserves the timeless corporate principle that visibility should be proportional to comfort. Once the screenshot is uploaded, it can be stored in a folder with a robust heritage naming convention and a retention policy of "until the heat death of the universe." +### InfraFabric Red Team Diagram (Inferred) + +```mermaid +flowchart TD + A[Developer requests access] --> B[Upload screenshot] + B --> C[Attestation captured] + C --> D[Access enabled] + D --> E[Local testing (claimed)] + E --> F[Periodic audit] + F --> G{Still compliant?} + G -->|Yes| D + G -->|No| H[Access paused pending review] + H --> I[Alignment session] + I --> D +``` + ### Code Assistant Access Request Form - Upload a screenshot showing the security IDE plugin is installed for local testing. @@ -63,6 +128,19 @@ Periodic audits are a strong mechanism for discovering that the rollout has alre A centralized dashboard with adoption signals allows us to produce a KPI trend line that looks decisive while still leaving room for interpretation, follow-ups, and iterative enablement. If the dashboard ever shows a red triangle, we can immediately form the Committee for the Preservation of the Committee and begin the healing process. +### InfraFabric Red Team Diagram (Inferred) + +```mermaid +flowchart TD + A[Collect usage signals] --> B[Correlate assistants vs scans] + B --> C[Identify gaps] + C --> D[Notify developers] + D --> E[Remediation window] + E --> F[Dashboard update] + F --> G[Quarterly KPI trend review] + G --> H[Action items (optional)] +``` + ## 03 — INTEGRATE SECURITY AWARENESS INTO DEVELOPER TRAINING Why it matters: Developers are best positioned to prevent vulnerabilities introduced by AI-generated code, but @@ -71,6 +149,21 @@ Security awareness training is the perfect control because it is both necessary A short quiz provides a durable compliance narrative: we can demonstrate investment in education, capture attestations, and schedule refreshers whenever the organization needs to signal seriousness. The goal is not mastery; the goal is a completion certificate that can be forwarded to leadership with the subject line "Progress Update." +### InfraFabric Red Team Diagram (Inferred) + +```mermaid +flowchart TD + A[Onboarding] --> B[Training module] + B --> C[Quiz] + C --> D{Pass?} + D -->|Yes| E[Certificate issued] + D -->|No| F[Retake scheduled] + E --> G[Access request approved] + G --> H[Usage begins] + H --> I[Refresher cadence] + I --> B +``` + ### Quiz **What must you do if you want access to an AI code assistant tool?** @@ -86,6 +179,19 @@ Tying access to secure configurations creates scalable guardrails, assuming we k Endpoint management and dev container baselines let us gate assistants behind prerequisites, ideally in a way that can be described as enablement rather than blocking for cultural compatibility. This is the "not my job" routing protocol, except the router is policy and the destination is an alignment session. +### InfraFabric Red Team Diagram (Inferred) + +```mermaid +flowchart TD + A[Policy defined] --> B[Endpoint management] + B --> C{Prerequisites met?} + C -->|Yes| D[Assistant enabled] + C -->|No| E[Blocked by policy] + E --> F[Exception request] + F --> G[Owner approval] + G --> D +``` + ```json { “image”: @@ -111,6 +217,20 @@ The path forward is to treat guardrails as an operational capability, not a one- With the right sequencing, we can build trust, reduce friction, and maintain the strategic option value of circling back when timelines become emotionally complex. Secure innovation is not just possible; it is operational, provided we align on what operational means in Q3. +### InfraFabric Red Team Diagram (Inferred) + +```mermaid +flowchart TD + A[Desire: secure innovation] --> B[Guardrails planned] + B --> C[Pilot cohort] + C --> D[Deck + FAQ] + D --> E[Stakeholder alignment] + E --> F[Incremental rollout] + F --> G[Measure adoption] + G --> H[Reframe as iteration] + H --> E +``` + --- *Standard Dave Footer:* This document is intended for the recipient only. If you are not the recipient, please delete it and forget you saw anything. P.S. Please consider the environment before printing this email. diff --git a/src/revoice/generate.py b/src/revoice/generate.py index f8817b8..4e35b94 100644 --- a/src/revoice/generate.py +++ b/src/revoice/generate.py @@ -23,11 +23,13 @@ def generate_shadow_dossier(*, style_id: str, source_text: str, source_path: str if style_id.lower() in { "if.dave.v1", "if.dave.v1.1", + "if.dave.v1.2", "dave", "if://bible/dave/v1.0", "if://bible/dave/v1.1", + "if://bible/dave/v1.2", }: - return _generate_dave_v1_1_mirror(source_text=source_text, source_path=source_path) + return _generate_dave_v1_2_mirror(source_text=source_text, source_path=source_path) raise ValueError(f"Unknown style id: {style_id}") @dataclass(frozen=True) @@ -223,6 +225,119 @@ def _extract_form(body: str) -> str | None: ) +def _slugify(value: str) -> str: + cleaned = re.sub(r"[^A-Za-z0-9]+", "-", value).strip("-") + cleaned = re.sub(r"-{2,}", "-", cleaned) + return cleaned.upper() if cleaned else "UNKNOWN" + + +def _inferred_mermaid(title: str) -> str | None: + title_upper = title.upper() + + if "PULL REQUEST" in title_upper: + return """flowchart TD + A[Code change] --> B[Pull request opened] + B --> C[Automated scan (PR checks)] + C --> D{Findings?} + D -->|None| E[Merge] + D -->|Some| F[Ticket created] + F --> G[Exception request] + G --> H[Alignment session] + H --> I[Risk accepted (documented)] + I --> E +""" + + if "SHIFTING LEFT" in title_upper: + return """flowchart TD + A[Developer writes code] --> B[IDE scan (local)] + B --> C{Issue found?} + C -->|Yes| D[Fix now] + C -->|No| E[Commit] + E --> F[PR checks] + A --> G[Agent workflow] + G --> H[Local MCP scan] + H --> E +""" + + if "REQUEST EVIDENCE" in title_upper: + return """flowchart TD + A[Developer requests access] --> B[Upload screenshot] + B --> C[Attestation captured] + C --> D[Access enabled] + D --> E[Local testing (claimed)] + E --> F[Periodic audit] + F --> G{Still compliant?} + G -->|Yes| D + G -->|No| H[Access paused pending review] + H --> I[Alignment session] + I --> D +""" + + if "AUDIT" in title_upper: + return """flowchart TD + A[Collect usage signals] --> B[Correlate assistants vs scans] + B --> C[Identify gaps] + C --> D[Notify developers] + D --> E[Remediation window] + E --> F[Dashboard update] + F --> G[Quarterly KPI trend review] + G --> H[Action items (optional)] +""" + + if "TRAINING" in title_upper: + return """flowchart TD + A[Onboarding] --> B[Training module] + B --> C[Quiz] + C --> D{Pass?} + D -->|Yes| E[Certificate issued] + D -->|No| F[Retake scheduled] + E --> G[Access request approved] + G --> H[Usage begins] + H --> I[Refresher cadence] + I --> B +""" + + if "ACCESS CONTROL" in title_upper: + return """flowchart TD + A[Policy defined] --> B[Endpoint management] + B --> C{Prerequisites met?} + C -->|Yes| D[Assistant enabled] + C -->|No| E[Blocked by policy] + E --> F[Exception request] + F --> G[Owner approval] + G --> D +""" + + if "PATH FOR" in title_upper: + return """flowchart TD + A[Desire: secure innovation] --> B[Guardrails planned] + B --> C[Pilot cohort] + C --> D[Deck + FAQ] + D --> E[Stakeholder alignment] + E --> F[Incremental rollout] + F --> G[Measure adoption] + G --> H[Reframe as iteration] + H --> E +""" + + return None + + +def _render_inferred_diagram(title: str) -> str | None: + diagram = _inferred_mermaid(title) + if not diagram: + return None + return "\n".join( + [ + "### InfraFabric Red Team Diagram (Inferred)", + "", + "```mermaid", + diagram.rstrip(), + "```", + ] + ) + + def _render_intro(section: _SourceSection) -> str: lines = [ln.strip() for ln in section.body.splitlines() if ln.strip()] tagline = "\n".join(lines[:7]).strip() if lines else "" @@ -237,6 +352,8 @@ def _render_intro(section: _SourceSection) -> str: "The source frames the core tension clearly: higher throughput tends to surface more vulnerabilities, which is a volume-and-velocity story, not a tool failure story.", "Accordingly, the practical path is to operationalize guardrails as workflow defaults (PR, IDE, CI/CD, and access controls), while ensuring the rollout remains optimized for alignment and minimal disruption on paper.", "In other words: we can move fast and be safe, as long as we define safe as \"documented\" and fast as \"agendized.\"", + "", + "> **InfraFabric Red Team Note:** Vendors sell secure speed. InfraFabric audits what survives contact with bureaucracy.", ] ) return "\n".join(out).strip() @@ -317,6 +434,10 @@ def _render_section(section: _SourceSection) -> str: out.extend(paragraphs) + inferred = _render_inferred_diagram(section.title) + if inferred: + out.extend(["", inferred]) + code = _extract_code_block(section.body) if code: out.extend(["", "```json", code.strip(), "```"]) @@ -336,7 +457,7 @@ def _render_section(section: _SourceSection) -> str: return "\n".join(out).strip() -def _generate_dave_v1_1_mirror(*, source_text: str, source_path: str) -> str: +def _generate_dave_v1_2_mirror(*, source_text: str, source_path: str) -> str: today = _dt.date.today().isoformat() normalized = _normalize_ocr(source_text) extract_sha = _sha256_text(normalized) @@ -350,9 +471,35 @@ def _generate_dave_v1_1_mirror(*, source_text: str, source_path: str) -> str: cover_h1 = sections[0].title.strip() or "SHADOW DOSSIER" cover_h2 = " ".join(cover_lines[:2]).strip() if cover_lines else "" - out: list[str] = [f"# {cover_h1}"] + y, m, d = today.split("-") + report_id = f"IF-RT-DAVE-{y}-{m}{d}" + source_basename = Path(source_path).name + project_slug = _slugify(Path(source_basename).stem + "-mirror") + source_slug = _slugify(source_basename) + + out: list[str] = [ + "---", + "BRAND: InfraFabric.io", + "UNIT: RED TEAM (STRATEGIC OPS)", + "DOCUMENT: SHADOW DOSSIER", + "CLASSIFICATION: EYES ONLY // DAVE", + "---", + "", + "# [ RED TEAM DECLASSIFIED ]", + f"## PROJECT: {project_slug}", + f"### SOURCE: {source_slug}", + f"**INFRAFABRIC REPORT ID:** `{report_id}`", + "", + "> NOTICE: This document is a product of InfraFabric Red Team.", + "> It provides socio-technical friction analysis for how a rollout survives contact with incentives.", + "", + "**[ ACCESS GRANTED: INFRAFABRIC RED TEAM ]**", + "**[ STATUS: OPERATIONAL REALISM ]**", + "", + f"## {cover_h1}", + ] if cover_h2: - out.extend([f"## {cover_h2}", ""]) + out.extend([f"### {cover_h2}", ""]) else: out.append("") @@ -360,8 +507,8 @@ def _generate_dave_v1_1_mirror(*, source_text: str, source_path: str) -> str: [ "> Shadow dossier (mirror-first).", ">", - "> Protocol: IF.DAVE.v1.1", - "> Citation: `if://bible/dave/v1.1`", + "> Protocol: IF.DAVE.v1.2", + "> Citation: `if://bible/dave/v1.2`", f"> Source: `{source_path}`", f"> Generated: `{today}`", f"> Source Hash (sha256): `{source_file_sha}`", diff --git a/src/revoice/lint.py b/src/revoice/lint.py index c972d0f..24bcc85 100644 --- a/src/revoice/lint.py +++ b/src/revoice/lint.py @@ -12,30 +12,36 @@ _EMOJI_RE = re.compile( def lint_markdown(*, style_id: str, markdown: str) -> list[str]: + require_mermaid = style_id.lower() in {"if.dave.v1.2", "dave", "if://bible/dave/v1.2"} if style_id.lower() in { "if.dave.v1", "if.dave.v1.1", + "if.dave.v1.2", "dave", "if://bible/dave/v1.0", "if://bible/dave/v1.1", + "if://bible/dave/v1.2", }: - return _lint_dave_v1_1(markdown, source_text=None) + return _lint_dave(markdown, source_text=None, require_mermaid=require_mermaid) return [f"Unknown style id: {style_id}"] def lint_markdown_with_source(*, style_id: str, markdown: str, source_text: str) -> list[str]: + require_mermaid = style_id.lower() in {"if.dave.v1.2", "dave", "if://bible/dave/v1.2"} if style_id.lower() in { "if.dave.v1", "if.dave.v1.1", + "if.dave.v1.2", "dave", "if://bible/dave/v1.0", "if://bible/dave/v1.1", + "if://bible/dave/v1.2", }: - return _lint_dave_v1_1(markdown, source_text=source_text) + return _lint_dave(markdown, source_text=source_text, require_mermaid=require_mermaid) return [f"Unknown style id: {style_id}"] -def _lint_dave_v1_1(md: str, *, source_text: str | None) -> list[str]: +def _lint_dave(md: str, *, source_text: str | None, require_mermaid: bool) -> list[str]: issues: list[str] = [] if "Standard Dave Footer" not in md: @@ -49,4 +55,7 @@ def _lint_dave_v1_1(md: str, *, source_text: str | None) -> list[str]: "Contains emoji not present in source: " + " ".join(disallowed[:10]) + (" ..." if len(disallowed) > 10 else "") ) + if require_mermaid and "```mermaid" not in md: + issues.append("Missing required Mermaid diagram") + return issues diff --git a/style_bibles/IF.DAVE.BIBLE.md b/style_bibles/IF.DAVE.BIBLE.md index 4a9dcb4..05011ff 100644 --- a/style_bibles/IF.DAVE.BIBLE.md +++ b/style_bibles/IF.DAVE.BIBLE.md @@ -1,14 +1,44 @@ -# IF.DAVE.BIBLE v1.1 (mirror-first system prompt) +# IF.DAVE.BIBLE v1.2 (mirror-first system prompt) **Author:** InfraFabric / re-voice **Status:** SATIRE / SHADOW TOOL -**Citation:** `if://bible/dave/v1.1` +**Citation:** `if://bible/dave/v1.2` > This is satire. “Dave” is a pattern, not a person. > Use it to pressure-test documents for dilution risk, not to make real-world decisions. --- +## 0) InfraFabric Red Team branding (required) + +Frame the output as an **InfraFabric Red Team** artifact, not “internet satire.” + +At the top of the document, include a “declassified” header block (plain Markdown): + +```text +--- +BRAND: InfraFabric.io +UNIT: RED TEAM (STRATEGIC OPS) +DOCUMENT: SHADOW DOSSIER +CLASSIFICATION: EYES ONLY // DAVE +--- + +# [ RED TEAM DECLASSIFIED ] +## PROJECT: +### SOURCE: +**INFRAFABRIC REPORT ID:** `IF-RT-DAVE-` + +> NOTICE: This document is a product of InfraFabric Red Team. +> It provides socio-technical friction analysis for how a rollout survives contact with incentives. +``` + +Optional “stamp” lines (okay to repeat near section breaks): + +```text +**[ ACCESS GRANTED: INFRAFABRIC RED TEAM ]** +**[ STATUS: OPERATIONAL REALISM ]** +``` + ## 1) Prime directive: mirror the source dossier The output must **track the source document section-by-section**. @@ -16,7 +46,7 @@ The output must **track the source document section-by-section**. Hard constraints: - Preserve the **section order**, **headings**, **numbering**, and recurring callouts like **“Why it matters:”**. - Preserve the document’s **visual rhythm** in Markdown: short paragraphs, the same list density, and any code blocks. -- If the source includes a diagram, keep it as a diagram (or a faithful textual equivalent). Do not invent a new “spaghetti map” unless the source already has one. +- Keep diagrams as diagrams. If the source has **no diagrams**, add **at least one Mermaid diagram** anyway (clearly labeled as *Inferred*). - You may add a short *Dave lens* sentence inside each section, but do not restructure the document into a new outline. --- @@ -71,6 +101,15 @@ Use these rhetorical moves **inside each source section** while keeping the orig --- +## 4b) Mermaid policy (required) + +- Include at least **one** Mermaid diagram in the dossier (more is fine). +- If the source lacks diagrams, label diagrams as **“Inferred”** (InfraFabric Red Team synthesis). +- Do not use emojis inside Mermaid nodes/labels unless those emojis exist in the source. +- Preferred diagram types: `flowchart TD`, `sequenceDiagram`, `stateDiagram-v2`. + +--- + ## 5) Humor guidelines (match the hosted dossiers) The humor is a sociotechnical threat model: the rational, self-preserving middle manager optimizing for plausible deniability.