diff --git a/ampg/manifest.py b/ampg/manifest.py index 247ec2b..e11f1b6 100644 --- a/ampg/manifest.py +++ b/ampg/manifest.py @@ -72,6 +72,7 @@ def _fixture_entry(site: SiteConfig, protocol: ProtocolConfig) -> dict[str, Any] "transport": transport, "profile": transport, }, + "interaction": _interaction_policy(protocol), } @@ -81,6 +82,16 @@ def _transport_for(protocol_name: str) -> str: return protocol_name +def _interaction_policy(protocol: ProtocolConfig) -> dict[str, Any]: + return { + "tier": str(protocol.options.get("tier", protocol.options.get("max_tier", "static"))), + "identity": str(protocol.options.get("identity", "none")), + "payments": str(protocol.options.get("payments", "none")), + "realtime": bool(protocol.options.get("realtime", False)), + "public_allowed": bool(protocol.options.get("public_allowed", True)), + } + + def _fixture_url(site: SiteConfig, protocol: ProtocolConfig) -> tuple[str, str]: configured_url = protocol.options.get("fixture_url") or protocol.options.get("browser_url") if configured_url: diff --git a/docs/fixture-manifests.md b/docs/fixture-manifests.md index c50ee82..03ee876 100644 --- a/docs/fixture-manifests.md +++ b/docs/fixture-manifests.md @@ -20,6 +20,8 @@ The manifest contains public route expectations only: - protocol renderer and relative output path. - route URL for AMPB checks. - expected AMPB transport and profile. +- declared interaction tier, identity adapter, payment adapter, realtime flag, and + public exposure flag. It must not contain private host inventory, hidden-service keys, tunnel keys, credentials, or deployment notes. @@ -39,3 +41,20 @@ manifest and does not rebuild protocol outputs. Some transports may not have final public addresses when a fixture is generated. In those cases AMPG uses route-valid placeholders such as `http://wownero.onion/` so AMPB can still verify transport selection without contacting the network. + +## Interaction Policy + +Fixture interaction policy defaults to: + +```json +{ + "tier": "static", + "identity": "none", + "payments": "none", + "realtime": false, + "public_allowed": true +} +``` + +Route-group overrides will be added separately. Until then, protocol-level options can +declare the fixture-level policy that AMPB should check. diff --git a/tests/test_fixture_manifest.py b/tests/test_fixture_manifest.py index e9173bf..de8b32c 100644 --- a/tests/test_fixture_manifest.py +++ b/tests/test_fixture_manifest.py @@ -73,6 +73,61 @@ cid = "bafyexample" self.assertEqual("gemini://example.test/", by_protocol["gemini"]["url"]) self.assertEqual("ipfs://bafyexample", by_protocol["ipfs"]["url"]) self.assertEqual({"transport": "ipfs", "profile": "ipfs"}, by_protocol["ipfs"]["checks"]) + self.assertEqual( + { + "identity": "none", + "payments": "none", + "public_allowed": True, + "realtime": False, + "tier": "static", + }, + by_protocol["ipfs"]["interaction"], + ) + + def test_manifest_includes_configured_interaction_policy(self): + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + source = root / "site" + source.mkdir() + (source / "index.html").write_text("