This commit is contained in:
Mateusz Gruszczyński committed 2026-10-11 23:09:59 +02:00
1 parent 79fd198949
commit 427d23cb6e
64 files changed
+138 -2979

No files matched your search

+5 -5
View File
@@ -73,7 +73,7 @@ for marker in [
]:
assert marker in update_check_source, marker
assert 'pub last_error:' not in update_check_source, "update-check errors must not change dashboard/API state"
for name in ["README.md", "ROADMAP.md", "AGENTS.md", "CHANGELOG.md", "UPDATE_CHECK.toml", "Dockerfile", ".dockerignore", "docs/TEST_REPORT.md", "docs/V0.24.8_AUDIT.md", "docs/V0.24.7_AUDIT.md", "docs/V0.24.6_AUDIT.md", "docs/V0.24.5_AUDIT.md", "docs/V0.24.1_AUDIT.md", "docs/V0.24.0_AUDIT.md", "docs/V0.23.2_AUDIT.md", "docs/V0.23.1_AUDIT.md", "docs/V0.22.3_AUDIT.md", "docs/LIVE_LOGS.md", "docs/README.md", "docs/API.md", "docs/ARCHITECTURE.md", "docs/WEB_SERVER.md", "docs/PHP_FPM.md", "docs/VHOSTS.md", "docs/STREAMS.md", "docs/REDIRECTS.md", "docs/CONTAINER.md", "docs/NPM_MIGRATION.md", "docs/DOCKER_DISCOVERY.md", "docker-agent/main.go", "docker-agent/main_test.go", "docker-agent/rustproxy-docker-agent.service", "docker-agent/docker-agent.env.example", "docker-agent/install.sh", "src/docker.rs", "src/admin/web/docker.js", "scripts/migration/migrate_npm.py", "docs/CUSTOM_LOCATIONS.md", "nagios/README.md", "nagios/check_rustproxy.py", "nagios/check_rustproxy_api", "nagios/check_rustproxy_backends", "nagios/check_rustproxy_latency", "nagios/check_rustproxy_queues", "src/admin/web/error_401.html", "src/admin/web/error_404.html", "src/admin/web/streams.js", "src/admin/web/redirects.js", "src/admin/web/host404.js", "docs/NOT_FOUND_HOSTS.md", "grafana/rustproxy-overview.json", "grafana/README.md"]:
for name in ["README.md", "ROADMAP.md", "AGENTS.md", "CHANGELOG.md", "UPDATE_CHECK.toml", "Dockerfile", ".dockerignore", "docs/TEST_REPORT.md", "docs/LIVE_LOGS.md", "docs/README.md", "docs/API.md", "docs/ARCHITECTURE.md", "docs/WEB_SERVER.md", "docs/PHP_FPM.md", "docs/VHOSTS.md", "docs/STREAMS.md", "docs/REDIRECTS.md", "docs/CONTAINER.md", "docs/NPM_MIGRATION.md", "docs/DOCKER_DISCOVERY.md", "docker-agent/main.go", "docker-agent/main_test.go", "docker-agent/rustproxy-docker-agent.service", "docker-agent/docker-agent.env.example", "docker-agent/install.sh", "src/docker.rs", "src/admin/web/docker.js", "scripts/migration/migrate_npm.py", "docs/CUSTOM_LOCATIONS.md", "nagios/README.md", "nagios/check_rustproxy.py", "nagios/check_rustproxy_api", "nagios/check_rustproxy_backends", "nagios/check_rustproxy_latency", "nagios/check_rustproxy_queues", "src/admin/web/error_401.html", "src/admin/web/error_404.html", "src/admin/web/streams.js", "src/admin/web/redirects.js", "src/admin/web/host404.js", "docs/NOT_FOUND_HOSTS.md", "grafana/rustproxy-overview.json", "grafana/README.md"]:
assert (root / name).is_file(), name
npm_doc = (root / "docs/NPM_MIGRATION.md").read_text(encoding="utf-8")
for marker in ["scripts/migration/migrate_npm_core.py", "scripts/migration/migrate_npm_api.py", '-v "$PWD/scripts/migration:/rustproxy-migration:ro"', "python /rustproxy-migration/migrate_npm.py"]:
@@ -1243,7 +1243,7 @@ assert 'rfc8441_requires_an_h2_capable_listener_and_h2c_is_explicit' in transpor
assert 'h2c' in integrations_0221 and 'H2C' in integrations_0221
transport_doc = (root / "docs/TRANSPORT.md").read_text()
assert 'prior knowledge' in transport_doc and 'Upgrade: h2c' in transport_doc and 'stream 1' in transport_doc
assert (root / "docs/V0.24.1_AUDIT.md").is_file() and (root / "docs/V0.24.0_AUDIT.md").is_file() and (root / "docs/V0.23.2_AUDIT.md").is_file() and (root / "docs/V0.23.1_AUDIT.md").is_file() and (root / "docs/V0.23.0_AUDIT.md").is_file() and (root / "docs/V0.22.3_AUDIT.md").is_file()
# Historical V0.22-0.24 audits are not required for active transport tests.
# 0.22.3 replay-safe retry and ordinary H2 upstream contracts.
balance_0222 = rust_source(root, "src/balance.rs")
@@ -1541,7 +1541,7 @@ for marker_0291 in ['rust_proxy_vhost_error_fallback_triggered_total', 'rust_pro
assert marker_0291 not in prometheus_0291, marker_0291
assert 'unavailable: host.transient_unavailable && host.source.is_reverse_proxy()' in rust_source(root, "src/config/routing.rs")
assert 'filter(|_| needs_proxy_pool)' in rust_source(root, "src/config/routing.rs")
assert (root / 'docs/V0.29.1_IMPLEMENTATION.md').is_file()
assert (root / 'docs/CUSTOM_LOCATIONS.md').is_file()
assert '"ErrorFallback"' in openapi and '"path_info"' in openapi and '"internal"' in openapi
# Retained 0.29.0 redirect/health/cache/gzip-log contracts.
@@ -1566,7 +1566,7 @@ assert 'redirect_location' in rust_source(root, "src/config/snapshot.rs") and 'l
assert 'pub struct UnsafeForce' in cache_entry_0290 and 'unsafe_force: UnsafeForce' in cache_entry_0290
assert 'forced_request_policy' in cache_request_0290 and 'cache_miss_forced' in rust_source(root, "src/proxy/mod.rs")
assert 'compressed: bool' in file_logs_0290 and 'GzDecoder' in file_logs_io_0290
for path_0290 in ['src/vhost/redirect.rs', 'docs/V0.29.0_IMPLEMENTATION.md']:
for path_0290 in ['src/vhost/redirect.rs']:
assert (root / path_0290).is_file(), path_0290
assert 'static_vhost_page_can_serve_html_with_503_status' in rust_source(root, "src/pages.rs")
assert 'upstream_uri_preserves_nested_url_query_without_rejecting_valid_separators' in rust_source(root, "src/proxy/mod.rs")
@@ -1631,7 +1631,7 @@ for marker_0282 in [
]:
assert marker_0282 in html or marker_0282 in runtime_web_0280 or marker_0282 in (root / 'langs/en_US.json').read_text(), marker_0282
assert 'Zewnętrzne ścieżki plików' in (root / 'langs/pl_pl.json').read_text()
assert 'setfacl -m u:rustproxy:--x /etc/ssl/' in (root / 'docs/V0.28.2_IMPLEMENTATION.md').read_text()
assert 'setfacl -m u:rustproxy:--x /etc/ssl/' in (root / 'docs/INSTALL.md').read_text()
print("PASS: 0.31.7 manifest/package, shared system-statistics/runtime metadata, Settings logging, retained H2, external-packaging/Grafana/Prometheus/404-host/custom-location/path/cache/dashboard/Nagios UI/source contracts, stopped legacy-renewal removal, session/admin/transport contracts, deterministic package source and embedded SQLite schema-v9 migrations.")
print("NOT VERIFIED: Rust parsing, types, compilation, linking or runtime behavior. Run ./dev.sh test.")
+4 -21
View File
@@ -14,25 +14,6 @@ required = [
DOCS / "README.md",
DOCS / "WEB_SERVER.md",
DOCS / "TODO.md",
DOCS / "V0.29.1_IMPLEMENTATION.md",
DOCS / "V0.29.0_IMPLEMENTATION.md",
DOCS / "V0.28.2_IMPLEMENTATION.md",
DOCS / "V0.28.1_IMPLEMENTATION.md",
DOCS / "V0.27.3_IMPLEMENTATION.md",
DOCS / "V0.27.2_IMPLEMENTATION.md",
DOCS / "V0.27.1_IMPLEMENTATION.md",
DOCS / "V0.27.0_IMPLEMENTATION.md",
DOCS / "V0.26.7_IMPLEMENTATION.md",
DOCS / "V0.25.5_AUDIT.md",
DOCS / "V0.25.4_AUDIT.md",
DOCS / "V0.25.3_AUDIT.md",
DOCS / "V0.25.2_AUDIT.md",
DOCS / "V0.25.1_AUDIT.md",
DOCS / "V0.25.0_AUDIT.md",
DOCS / "IMPLEMENTATION_0.31.5.md",
DOCS / "IMPLEMENTATION_0.31.7.md",
DOCS / "IMPLEMENTATION_0.31.3.md",
DOCS / "IMPLEMENTATION_0.31.1.md",
DOCS / "TEST_REPORT.md",
DOCS / "CHANGELOG_TECHNICAL_ARCHIVE.md",
DOCS / "ROADMAP_HISTORY.md",
@@ -41,10 +22,10 @@ for path in required:
assert path.is_file(), f"missing required documentation: {path.relative_to(ROOT)}"
index = (DOCS / "README.md").read_text(encoding="utf-8")
for marker in ["Functional documentation", "Development and testing", "Technical documentation", "Historical or version-labelled context", "TODO.md", "V0.25.5_AUDIT.md", "V0.25.4_AUDIT.md", "V0.25.3_AUDIT.md", "V0.25.2_AUDIT.md", "V0.25.1_AUDIT.md", "V0.25.0_AUDIT.md", "CHANGELOG_TECHNICAL_ARCHIVE.md", "ROADMAP_HISTORY.md", "/docs"]:
for marker in ["Functional documentation", "Development and testing", "Technical documentation", "Historical or version-labelled context", "TODO.md", "SECURITY_AUDIT_0.31.0.md", "CHANGELOG_TECHNICAL_ARCHIVE.md", "ROADMAP_HISTORY.md", "/docs"]:
assert marker in index, marker
for document in sorted(DOCS.glob("*.md")):
if document.name == "README.md" or (document.name.startswith("V") and document.name.endswith("_AUDIT.md")):
if document.name == "README.md":
continue
assert document.name in index, f"documentation index does not classify {document.name}"
@@ -63,6 +44,8 @@ assert 'docs-content.json' not in documentation_rs and 'documentation_bundle' no
for document in sorted(DOCS.glob("*.md")):
marker = f'"{document.relative_to(ROOT).as_posix()}"'
assert marker in documentation_rs, f"Reader does not embed {document.relative_to(ROOT)}"
for path in set(re.findall(r'"(docs/[A-Za-z0-9_.-]+\.md)"', documentation_rs)):
assert (ROOT / path).is_file(), f"Reader embeds missing document: {path}"
assert '"/docs/content.json"' in admin
readme = (ROOT / "README.md").read_text(encoding="utf-8")
+14 -1
View File
@@ -3,6 +3,7 @@
from __future__ import annotations
import argparse
import hashlib
import re
from pathlib import Path
import sys
@@ -73,9 +74,21 @@ def check(root: Path, repair_known: bool = False) -> list[str]:
flat = module.parent.with_suffix(".rs")
if flat.is_file():
raise ValueError(f"Conflicting Rust modules: {flat.relative_to(root)} and {module.relative_to(root)}")
for path in ["src/auth/mod.rs", "src/auth/store.rs", "src/backup/snapshot.rs", "src/upstream.rs", "src/tls.rs", "src/config/internal_routing.rs", "src/proxy/websocket.rs", "src/proxy/error_fallback.rs", "src/cache/mod.rs", "src/cache/model.rs", "src/cache/lifecycle.rs", "src/cache/cold.rs", "src/cache/dashboard.rs", "src/cache/tickets.rs", "src/cache/lookup.rs", "src/cache/policy.rs", "src/cache/fill.rs", "src/cache/tests.rs", "src/settings.rs", "src/compression.rs", "src/diagnostics.rs", "src/traffic.rs", "src/system_stats/mod.rs", "src/system_stats/linux.rs", "src/vhost.rs", "src/vhost/error_fallback.rs", "src/web_server/mod.rs", "src/web_server/config.rs", "src/web_server/filesystem.rs", "src/web_server/security.rs", "src/web_server/response.rs", "src/web_server/request.rs", "src/web_server/routing.rs", "src/web_server/fastcgi.rs", "src/web_server/htaccess.rs", "src/web_server/serve.rs", "src/web_server/tests.rs", "src/balance.rs", "src/security.rs", "src/admin/web/vhosts/core.js", "src/admin/web/vhosts/rates.js", "src/admin/web/vhosts/health.js", "src/admin/web/vhosts/editor.js", "src/admin/web/vhosts/render.js", "src/admin/web/web-server.js", "src/admin/web/streams.js", "src/admin/web/host404.js", "src/admin/web/app/core.js", "src/admin/web/app/session-resume.js", "src/admin/web/app/preferences.js", "src/admin/web/app/config-history.js", "src/admin/web/app/runtime.js", "src/admin/web/app/settings.js", "src/admin/web/management.js", "src/admin/web/drafts.js", "src/pages.rs", "tools/dev/mock_server.py", "tools/dev/mock_auth.py", "src/forwarding.rs", "src/tinyauth.rs", "src/http3.rs", "src/stream.rs", "src/admin/web/integrations.js", "src/admin/web/traffic-panel.js", "src/prometheus.rs", "src/admin/web/settings.js", "src/admin/web/docker.js", "src/docker.rs", "docker-agent/main.go", "docker-agent/model.go", "docker-agent/docker.go", "docker-agent/network.go", "docker-agent/certificate.go", "docker-agent/server.go", "docker-agent/main_test.go", "docker-agent/rustproxy-docker-agent.service", "docker-agent/install.sh", "docs/DOCKER_DISCOVERY.md", "docs/WEB_SERVER.md", "docs/PHP_FPM.md", "docs/README.md", "docs/TODO.md", "docs/V0.25.5_AUDIT.md", "docs/V0.25.4_AUDIT.md", "docs/V0.25.3_AUDIT.md", "docs/V0.25.2_AUDIT.md", "docs/CHANGELOG_TECHNICAL_ARCHIVE.md", "docs/ROADMAP_HISTORY.md", "tools/checks/docs_check.py", "tools/checks/web_server_contracts.py", "tools/checks/rust_source.py", "tools/checks/rust_module_contracts.py", "tools/checks/source_module_contracts.py", "scripts/runtime/acme_provider.py", "src/basic_auth.rs", "scripts/deploy/deploy.py", "scripts/deploy/deploy_core.py", "scripts/deploy/deploy_runtime.py", "scripts/migration/migrate_npm.py", "scripts/migration/migrate_npm_core.py", "scripts/migration/migrate_npm_api.py", "docs/NPM_MIGRATION.md", "docs/STREAMS.md", "install.sh", "install-debian13.sh", "update.sh", "build.rs", "scripts/build/swagger_assets.py", "src/admin/documentation.rs", "src/admin/openapi.json", "langs/en_US.json", "langs/pl_pl.json", "Dockerfile", ".dockerignore", "docs/CONTAINER.md", "docs/PROMETHEUS.md", "docs/NOT_FOUND_HOSTS.md", "grafana/rustproxy-overview.json"]:
for path in ["src/auth/mod.rs", "src/auth/store.rs", "src/backup/snapshot.rs", "src/upstream.rs", "src/tls.rs", "src/config/internal_routing.rs", "src/proxy/websocket.rs", "src/proxy/error_fallback.rs", "src/cache/mod.rs", "src/cache/model.rs", "src/cache/lifecycle.rs", "src/cache/cold.rs", "src/cache/dashboard.rs", "src/cache/tickets.rs", "src/cache/lookup.rs", "src/cache/policy.rs", "src/cache/fill.rs", "src/cache/tests.rs", "src/settings.rs", "src/compression.rs", "src/diagnostics.rs", "src/traffic.rs", "src/system_stats/mod.rs", "src/system_stats/linux.rs", "src/vhost.rs", "src/vhost/error_fallback.rs", "src/web_server/mod.rs", "src/web_server/config.rs", "src/web_server/filesystem.rs", "src/web_server/security.rs", "src/web_server/response.rs", "src/web_server/request.rs", "src/web_server/routing.rs", "src/web_server/fastcgi.rs", "src/web_server/htaccess.rs", "src/web_server/serve.rs", "src/web_server/tests.rs", "src/balance.rs", "src/security.rs", "src/admin/web/vhosts/core.js", "src/admin/web/vhosts/rates.js", "src/admin/web/vhosts/health.js", "src/admin/web/vhosts/editor.js", "src/admin/web/vhosts/render.js", "src/admin/web/web-server.js", "src/admin/web/streams.js", "src/admin/web/host404.js", "src/admin/web/app/core.js", "src/admin/web/app/session-resume.js", "src/admin/web/app/preferences.js", "src/admin/web/app/config-history.js", "src/admin/web/app/runtime.js", "src/admin/web/app/settings.js", "src/admin/web/management.js", "src/admin/web/drafts.js", "src/pages.rs", "tools/dev/mock_server.py", "tools/dev/mock_auth.py", "src/forwarding.rs", "src/tinyauth.rs", "src/http3.rs", "src/stream.rs", "src/admin/web/integrations.js", "src/admin/web/traffic-panel.js", "src/prometheus.rs", "src/admin/web/settings.js", "src/admin/web/docker.js", "src/docker.rs", "docker-agent/main.go", "docker-agent/model.go", "docker-agent/docker.go", "docker-agent/network.go", "docker-agent/certificate.go", "docker-agent/server.go", "docker-agent/main_test.go", "docker-agent/rustproxy-docker-agent.service", "docker-agent/install.sh", "docs/DOCKER_DISCOVERY.md", "docs/WEB_SERVER.md", "docs/PHP_FPM.md", "docs/README.md", "docs/TODO.md", "docs/CHANGELOG_TECHNICAL_ARCHIVE.md", "docs/ROADMAP_HISTORY.md", "tools/checks/docs_check.py", "tools/checks/web_server_contracts.py", "tools/checks/rust_source.py", "tools/checks/rust_module_contracts.py", "tools/checks/source_module_contracts.py", "scripts/runtime/acme_provider.py", "src/basic_auth.rs", "scripts/deploy/deploy.py", "scripts/deploy/deploy_core.py", "scripts/deploy/deploy_runtime.py", "scripts/migration/migrate_npm.py", "scripts/migration/migrate_npm_core.py", "scripts/migration/migrate_npm_api.py", "docs/NPM_MIGRATION.md", "docs/STREAMS.md", "install.sh", "install-debian13.sh", "update.sh", "build.rs", "scripts/build/swagger_assets.py", "src/admin/documentation.rs", "src/admin/openapi.json", "langs/en_US.json", "langs/pl_pl.json", "Dockerfile", ".dockerignore", "docs/CONTAINER.md", "docs/PROMETHEUS.md", "docs/NOT_FOUND_HOSTS.md", "grafana/rustproxy-overview.json"]:
if not (root / path).is_file():
raise ValueError(f"Incomplete RustProxy 0.31.7 source tree: missing {path}")
# The Reader uses compile-time include_str! for its bundled Markdown. A
# dangling registration is a real compiler error, unlike an omitted old
# release audit. Match both reader_doc! and the expanded include_str! form.
registry = root / "src/admin/documentation/documents.rs"
if not registry.is_file():
raise ValueError("Incomplete RustProxy 0.31.7 source tree: missing src/admin/documentation/documents.rs")
embedded_docs = set(re.findall(
r'"(docs/[A-Za-z0-9_.-]+\.md)"', registry.read_text(encoding="utf-8")
))
for doc_path in sorted(embedded_docs):
if not (root / doc_path).is_file():
raise ValueError(f"Missing embedded Reader document: {doc_path}; restore the file or remove its Reader registration")
text = (root / "src/lib.rs").read_text(encoding="utf-8")
if '#[path = "auth/mod.rs"]' not in text:
raise ValueError("src/lib.rs is not the 0.31.7 entry point; extract the complete package, not individual files.")
+2 -8
View File
@@ -654,14 +654,8 @@ def source_contract_smoke() -> None:
transport_0223 = (ROOT / "docs/TRANSPORT.md").read_text(encoding="utf-8")
assert 'Upgrade: h2c' in transport_0223 and 'stream 1' in transport_0223
assert 'legacy HTTP/1.1 Upgrade-to-h2c is not implemented' not in transport_0223
audit_0233 = (ROOT / "docs/V0.24.0_AUDIT.md").read_text(encoding="utf-8")
audit_0232 = (ROOT / "docs/V0.23.2_AUDIT.md").read_text(encoding="utf-8")
audit_0223 = (ROOT / "docs/V0.22.3_AUDIT.md").read_text(encoding="utf-8")
for marker in ["legacy websocket", "origin", "http/1.1", "sec-websocket-accept", "ilo4"]:
assert marker.lower() in audit_0233.lower(), marker
for marker in ["600 samples", "308", "HTTPS", "<data-dir>/certs", "--livelogs"]:
assert marker.lower() in audit_0232.lower(), marker
assert 'external certificate ownership model' in audit_0223.lower() and 'release gate' in audit_0223.lower()
# Obsolete specification audit files were intentionally removed; the
# source/transport assertions above remain the executable regressions.
update_check = rust_source(ROOT, "src/update_check.rs")
update_defaults = tomllib.loads((ROOT / "UPDATE_CHECK.toml").read_text(encoding="utf-8"))
+47
View File
@@ -0,0 +1,47 @@
#!/usr/bin/env python3
"""Verify removed history is optional, but live embedded documents remain required."""
from __future__ import annotations
from pathlib import Path
import shutil
import sys
from tempfile import TemporaryDirectory
from preflight import check
ROOT = Path(__file__).resolve().parents[2]
# A compact 0.31.7 source tree may omit historical version-labelled documents.
# It must still pass the same preflight used by every ./dev.sh command.
assert check(ROOT) == []
with TemporaryDirectory(prefix="rustproxy-pruned-source-") as tmp:
stripped = Path(tmp) / "RustProxy"
shutil.copytree(
ROOT, stripped,
ignore=shutil.ignore_patterns(".git", "target", "data", ".upgrade-backup", "__pycache__"),
)
# This functional document is in the Reader registry, but intentionally not
# in the legacy hand-maintained required-file list. It must still be caught.
reader_doc = stripped / "docs/REFERENCES.md"
assert reader_doc.is_file(), "Missing test fixture: docs/REFERENCES.md"
reader_doc.unlink()
try:
check(stripped)
except ValueError as error:
assert "Missing embedded Reader document: docs/REFERENCES.md" in str(error), error
else:
raise AssertionError("Preflight accepted missing compile-time embedded document")
shutil.copy2(ROOT / "docs/REFERENCES.md", reader_doc)
required_module = stripped / "src/cache/mod.rs"
required_module.unlink()
try:
check(stripped)
except ValueError as error:
assert "missing src/cache/mod.rs" in str(error), error
else:
raise AssertionError("Preflight accepted missing runtime source")
print("PASS: pruned historical documents are optional; embedded Reader files and runtime sources are mandatory.")
-4
View File
@@ -208,10 +208,6 @@ assert "Source" in openapi.get("components", {}).get("schemas", {})
assert "client_ips" in openapi["components"]["schemas"]["TrafficCounters"]["properties"]
assert (ROOT / "docs/WEB_SERVER.md").is_file()
assert (ROOT / "docs/PHP_FPM.md").is_file()
assert (ROOT / "docs/V0.25.5_AUDIT.md").is_file()
assert (ROOT / "docs/V0.25.4_AUDIT.md").is_file()
assert (ROOT / "docs/V0.25.2_AUDIT.md").is_file()
assert (ROOT / "docs/V0.25.0_AUDIT.md").is_file()
assert (ROOT / "docs/TODO.md").is_file()
docs_html = (ROOT / "src/admin/web/docs.html").read_text()
docs_js = (ROOT / "src/admin/web/docs.js").read_text()