diff --git a/README.md b/README.md index 657567b..8fc233b 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Software supply-chain security is a cross-cutting supplemental domain, **Layer S - The immutable [F7-LAS whitepaper v3.0](docs/F7-LAS-model-whitepaper_v3.0.pdf) - A draft [implementation guide](docs/f7-las-implementation-guide/README.md) - A draft [46-control catalog](docs/F7-LAS-Control-Catalog-v0.1.md) -- Architecture diagrams and engineering review material +- Current [architecture diagrams](docs/architecture-diagrams.md), with explicit implementation boundaries, and engineering review material - Canonical v1.0.0 data contracts and one synthetic, offline Python + OPA workflow - Illustrative prompts, additional policies, validators, and runtime stubs - Supply-chain CI, behavioral tests, evidence verification, deterministic replay, @@ -86,6 +86,7 @@ These commands validate the **current prototype and repository structure**. They - [Canonical offline workflow](examples/canonical-workflow/README.md) - [Supply-chain and CI controls](docs/supply-chain-and-ci.md) - [Clean-user acceptance](docs/clean-user-acceptance.md) +- [Architecture diagrams](docs/architecture-diagrams.md) - [Roadmap](ROADMAP.md) - [Security policy](SECURITY.md) diff --git a/config/prompts/F7-LAS-Model-v1.png b/config/prompts/F7-LAS-Model-v1.png deleted file mode 100644 index dde38bb..0000000 Binary files a/config/prompts/F7-LAS-Model-v1.png and /dev/null differ diff --git a/docs/F7-LAS-Model-v1.png b/docs/F7-LAS-Model-v1.png deleted file mode 100644 index 70cf953..0000000 Binary files a/docs/F7-LAS-Model-v1.png and /dev/null differ diff --git a/docs/F7-LAS-QA.md b/docs/F7-LAS-QA.md index 5d93947..0c6018f 100644 --- a/docs/F7-LAS-QA.md +++ b/docs/F7-LAS-QA.md @@ -51,6 +51,17 @@ PDP/PEP boundaries. The current Layer 6 demonstration is a synthetic in-process executor that makes no network calls; it is not an OS/container sandbox or an enforced network-isolation boundary. +## How should the architecture diagrams be interpreted? + +The [architecture diagrams](architecture-diagrams.md) describe F7-LAS control +responsibilities and the governed execution flow. They are not deployment +diagrams or proof that a control is implemented. Layer numbers identify control +domains rather than a universally linear runtime order: a Layer 4 action is +proposed before Layer 5 authorization, while actual Layer 4 tool access is +allowed only after permit and within the applicable Layer 6 boundary. The +diagram guide maps every visual stage to the bounded canonical implementation +and states the unimplemented production boundaries. + ## What do evidence verification and replay prove? The canonical verifier independently checks the complete record chain, diff --git a/docs/README.md b/docs/README.md index 5376eb6..bae4500 100644 --- a/docs/README.md +++ b/docs/README.md @@ -15,10 +15,15 @@ This directory contains the governed documentation for the F7-LAS seven-layer re - [Canonical offline workflow](../examples/canonical-workflow/README.md) — the bounded synthetic Python + OPA Layers 1–7 demonstration. - [Supply-chain and CI controls](supply-chain-and-ci.md) — implemented dependency, action, download, vulnerability, secret, and SBOM checks and their limits. - [Clean-user acceptance](clean-user-acceptance.md) — the exact supported environment, complete walkthrough, command inventory, and assurance boundary. +- [Architecture diagrams](architecture-diagrams.md) — executive and layer-specific F7-LAS control-loop views, with an explicit implementation mapping and assurance boundary. ## Architecture graphics -Existing diagrams remain under `docs/` and `docs/images/` while their references and semantics are inventoried. They are historical/current draft visuals, not evidence of implemented behavior. Purpose-built replacement diagrams will be created only after the canonical execution semantics are approved. +The [current architecture diagrams](architecture-diagrams.md) describe the +F7-LAS control model at executive and layer-specific levels. Their semantic map +states exactly which elements the bounded canonical path implements and which +remain reference-architecture requirements. A diagram is not evidence of +production readiness or control effectiveness. ## Status and use diff --git a/docs/architecture-diagrams.md b/docs/architecture-diagrams.md new file mode 100644 index 0000000..826d1ee --- /dev/null +++ b/docs/architecture-diagrams.md @@ -0,0 +1,81 @@ +# F7-LAS Architecture Diagrams + +These diagrams describe the F7-LAS responsibility model and governed execution +flow. They are architecture views, not evidence that every depicted control is +implemented by this repository. The only executable path currently supported +is the bounded synthetic workflow documented under +[`examples/canonical-workflow/`](../examples/canonical-workflow/README.md). + +## Executive control loop + +![F7-LAS executive control loop for agentic systems](images/F7-LAS-Executive-Control-Loop.png) + +This view summarizes the governance path for an executive audience: mission +context, an action proposal, policy decision, conditional human approval, +enforcement, scoped execution, validation, monitoring, and governed feedback. +An approval-required outcome returns to the PDP for reevaluation. Only a PDP +permit may proceed to PEP enforcement, and PEP authorization occurs before tool +access or execution. Deny/block and clarify/refer-to-human are distinct terminal +outcomes. + +## Layer-specific execution control loop + +![F7-LAS agentic execution control loop](images/F7-LAS-Agentic-Execution-Control-Loop.png) + +This view maps the same control loop to F7-LAS Layers 1–7. Layer numbers name +responsibility domains; they do not require every runtime event to occur in +numeric order. In particular, Layer 4 first defines a proposed tool action as +data before Layer 5 authorization. Actual Layer 4 tool access may occur only +after permit and successful PEP enforcement, within the applicable Layer 6 +execution boundary. Human approval never bypasses the PDP or PEP. + +## Canonical implementation alignment + +| Diagram concept | Canonical repository behavior | +|---|---| +| Mission request and context | `request` and `context` records establish the fixed mission, actor, evidence, and lab scope. | +| Agent Planning and action proposal | A deterministic `plan` produces one `proposed_action`; the proposal has no authority to execute. No LLM or private chain-of-thought is used or recorded. | +| Policy decision point | OPA evaluates the complete action, scope, approval binding, execution time, and policy-bundle digest, then permits or denies fail closed. | +| Conditional human approval | The canonical fixture creates deterministic synthetic approval evidence before the `policy_decision` record. It demonstrates binding and expiry enforcement, not an interactive approval service or verified human identity. | +| PEP enforcement | Only a PDP permit reaches the PEP. The PEP verifies the decision and its action, approval, scope, policy, obligation, and expiry bindings before authorizing access. | +| Scoped execution and tool access | Only after PEP authorization does the permit path enter the Layer 6 boundary and invoke one registered, synthetic, read-only in-process executor. It makes no network or external API call and independently rechecks the complete binding. | +| Validation, monitoring, and evaluation | `execution_result` and `audit_event` records preserve the outcome; evidence verification and deterministic replay check their correlations and digests. This is not production telemetry or continuous monitoring. | +| Feedback and continuous assurance | Test, review, policy, prompt, and process changes use the normal governed repository workflow. The implementation does not self-modify. | + +The permit flow is therefore: + +1. admit a request and context; +2. create a bounded plan and proposed Layer 4 action; +3. bind any required approval to the exact request, action, scope, policy, authority, and validity window; +4. obtain or reevaluate a Layer 5 PDP decision, returning any human approval to the PDP; +5. on PDP permit only, enforce the complete authorization at the PEP; +6. after PEP authorization, enter the Layer 6 boundary and perform the registered synthetic action; +7. emit correlated Layer 7 result and audit evidence. + +A denial or invalid prerequisite stops before execution and still preserves +canonical evidence when admission succeeded. + +## Assurance boundary + +The diagrams express the intended F7-LAS control architecture. In this +repository, Layer 6 is a synthetic in-process executor—not an OS/container +sandbox, network-isolation boundary, or production least-privilege runtime. +The repository does not provide production integrations, autonomous response, +live human approval, external identity proofing, or a deployed monitoring +system. See [QA and current maturity](F7-LAS-QA.md) for the complete boundary. + +## Asset integrity and attribution + +Both diagrams are authored F7-LAS content by Anthony L. Fuller and are covered +by [CC BY 4.0](../LICENSE-CONTENT.md). Copyright licensing does not grant +F7-LAS trademark rights or imply endorsement. + +| File | Dimensions | SHA-256 | +|---|---:|---| +| `images/F7-LAS-Executive-Control-Loop.png` | 1672 × 941 | `23449ac61fc65089d96956d5900916f69ee637960d83a46ff847093e3da59159` | +| `images/F7-LAS-Agentic-Execution-Control-Loop.png` | 1672 × 941 | `9f4400b86796f1f047e51f595f416be5c2c398801a146778833a821277cdd8d6` | + +Legacy draft graphics were removed from the current documentation set because +they contained ambiguous execution routing, private-reasoning terminology, or +unsupported active-remediation claims. The immutable whitepaper PDF was not +modified. diff --git a/docs/images/F7-LAS-Agentic-Execution-Control-Loop.png b/docs/images/F7-LAS-Agentic-Execution-Control-Loop.png new file mode 100644 index 0000000..f42c9e5 Binary files /dev/null and b/docs/images/F7-LAS-Agentic-Execution-Control-Loop.png differ diff --git a/docs/images/F7-LAS-Executive-Control-Loop.png b/docs/images/F7-LAS-Executive-Control-Loop.png new file mode 100644 index 0000000..1e574ef Binary files /dev/null and b/docs/images/F7-LAS-Executive-Control-Loop.png differ diff --git a/docs/images/F7-LAS-Model-v1A.png b/docs/images/F7-LAS-Model-v1A.png deleted file mode 100644 index 985c867..0000000 Binary files a/docs/images/F7-LAS-Model-v1A.png and /dev/null differ diff --git a/docs/images/F7-LAS-Model-v1B.png b/docs/images/F7-LAS-Model-v1B.png deleted file mode 100644 index f1f1ed9..0000000 Binary files a/docs/images/F7-LAS-Model-v1B.png and /dev/null differ diff --git a/docs/images/F7-LAS_Execution_Control_Loop.png b/docs/images/F7-LAS_Execution_Control_Loop.png deleted file mode 100644 index 9cdd95a..0000000 Binary files a/docs/images/F7-LAS_Execution_Control_Loop.png and /dev/null differ diff --git a/docs/images/Multi-Agent-F7-LAS_Model-v1.png b/docs/images/Multi-Agent-F7-LAS_Model-v1.png deleted file mode 100644 index 11e1ecd..0000000 Binary files a/docs/images/Multi-Agent-F7-LAS_Model-v1.png and /dev/null differ diff --git a/scripts/validate-documentation.py b/scripts/validate-documentation.py index cacbac2..afa90d1 100755 --- a/scripts/validate-documentation.py +++ b/scripts/validate-documentation.py @@ -3,7 +3,9 @@ from __future__ import annotations +import hashlib import re +import struct import sys from pathlib import Path from urllib.parse import unquote, urlsplit @@ -21,6 +23,35 @@ Path("schemas/contracts/README.md"), } IGNORED_DIRECTORIES = {".git", ".venv", "venv", "node_modules", "__pycache__"} +EXPECTED_DIAGRAMS = { + Path("docs/images/F7-LAS-Executive-Control-Loop.png"): ( + "23449ac61fc65089d96956d5900916f69ee637960d83a46ff847093e3da59159", + (1672, 941), + ), + Path("docs/images/F7-LAS-Agentic-Execution-Control-Loop.png"): ( + "9f4400b86796f1f047e51f595f416be5c2c398801a146778833a821277cdd8d6", + (1672, 941), + ), +} +RETIRED_DIAGRAMS = { + Path("config/prompts/F7-LAS-Model-v1.png"), + Path("docs/F7-LAS-Model-v1.png"), + Path("docs/images/F7-LAS-Model-v1A.png"), + Path("docs/images/F7-LAS-Model-v1B.png"), + Path("docs/images/F7-LAS_Execution_Control_Loop.png"), + Path("docs/images/Multi-Agent-F7-LAS_Model-v1.png"), +} +REQUIRED_DIAGRAM_NOTICES = { + "Layer numbers name responsibility domains", + "proposal has no authority to execute", + "synthetic in-process executor—not an OS/container sandbox", + "The implementation does not self-modify", + "returns to the PDP for reevaluation", + "Only a PDP permit may proceed to PEP enforcement", + "PEP authorization occurs before tool access or execution", + "distinct terminal outcomes", + "Agent Planning", +} class DocumentationError(ValueError): @@ -109,11 +140,45 @@ def validate_command_boundaries(path: Path, root: Path) -> None: ) +def validate_png(path: Path, expected_digest: str, expected_size: tuple[int, int]) -> None: + try: + content = path.read_bytes() + except OSError as exc: + raise DocumentationError(f"missing canonical diagram asset: {path}") from exc + if hashlib.sha256(content).hexdigest() != expected_digest: + raise DocumentationError(f"canonical diagram digest mismatch: {path}") + if len(content) < 24 or content[:8] != b"\x89PNG\r\n\x1a\n": + raise DocumentationError(f"canonical diagram is not a valid PNG: {path}") + width, height = struct.unpack(">II", content[16:24]) + if (width, height) != expected_size: + raise DocumentationError( + f"canonical diagram dimensions mismatch: {path}: {(width, height)}" + ) + + +def validate_diagrams(root: Path) -> None: + for relative, (digest, dimensions) in EXPECTED_DIAGRAMS.items(): + validate_png(root / relative, digest, dimensions) + for relative in RETIRED_DIAGRAMS: + if (root / relative).exists(): + raise DocumentationError(f"retired legacy diagram returned: {relative}") + + guide = (root / "docs" / "architecture-diagrams.md").read_text(encoding="utf-8") + normalized_guide = " ".join(guide.split()) + for notice in REQUIRED_DIAGRAM_NOTICES: + if notice not in normalized_guide: + raise DocumentationError( + f"architecture diagram guide is missing required semantics: {notice}" + ) + + def validate_repository(root: Path = ROOT) -> None: for path in markdown_files(root): validate_links(path, root) validate_command_boundaries(path, root) + validate_diagrams(root) + illustrative_opa = ( root / "examples" / "layer5-policy-engines" / "opa-rego" / "README.md" ).read_text(encoding="utf-8") diff --git a/tests/test_documentation.py b/tests/test_documentation.py index 7780d8d..fd12a08 100644 --- a/tests/test_documentation.py +++ b/tests/test_documentation.py @@ -56,6 +56,31 @@ def test_bare_pytest_command_is_rejected(tmp_path: Path) -> None: MODULE.validate_command_boundaries(document, tmp_path) +def test_substituted_canonical_diagram_is_rejected(tmp_path: Path) -> None: + source = ROOT / "docs" / "images" / "F7-LAS-Executive-Control-Loop.png" + substituted = tmp_path / source.name + substituted.write_bytes(source.read_bytes() + b"substituted") + with pytest.raises(MODULE.DocumentationError, match="diagram digest mismatch"): + MODULE.validate_png( + substituted, + MODULE.EXPECTED_DIAGRAMS[ + Path("docs/images/F7-LAS-Executive-Control-Loop.png") + ][0], + (1672, 941), + ) + + +def test_control_loop_semantics_are_required() -> None: + expected = { + "returns to the PDP for reevaluation", + "Only a PDP permit may proceed to PEP enforcement", + "PEP authorization occurs before tool access or execution", + "distinct terminal outcomes", + "Agent Planning", + } + assert expected <= MODULE.REQUIRED_DIAGRAM_NOTICES + + def test_clean_user_gate_rejects_substituted_opa(tmp_path: Path) -> None: fake_opa = tmp_path / "opa" fake_opa.write_text("#!/bin/sh\necho 'Version: 1.20.2'\n", encoding="utf-8")