Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/profile-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Profile checks

on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:

permissions:
contents: read

jobs:
parity:
runs-on: ${{ matrix.os }}
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: python -m pip install pytest
- name: Check profile parity and privacy boundaries
env:
PROFILE_PRIVATE_REPO_DENYLIST: ${{ secrets.PROFILE_PRIVATE_REPO_DENYLIST }}
run: python -m pytest -q
21 changes: 21 additions & 0 deletions tests/test_private_guard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""Synthetic checks for the externally configured profile privacy guard."""
import pytest

from test_profile_parity import check_public_profile


def test_public_links_checked_without_private_inventory(monkeypatch):
monkeypatch.delenv("PROFILE_PRIVATE_REPO_DENYLIST", raising=False)
check_public_profile("https://github.com/dev-bricks/CodeBox")
with pytest.raises(AssertionError, match="unlisted repository"):
check_public_profile("https://github.com/dev-bricks/synthetic-unlisted")


@pytest.mark.parametrize("separator", [",", ";", "\n", " "])
def test_configured_guard_redacts_failure(monkeypatch, separator):
name = "synthetic-private-project"
monkeypatch.setenv("PROFILE_PRIVATE_REPO_DENYLIST", f"other{separator}{name}")
with pytest.raises(AssertionError) as caught:
check_public_profile(name.upper())
assert name not in str(caught.value).casefold()
check_public_profile("Ordinary public profile text")
24 changes: 12 additions & 12 deletions tests/test_profile_parity.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Text and link parity checks for dev-bricks organization profile, inventory, and public metadata."""

import os
import re
from pathlib import Path
import pytest
Expand Down Expand Up @@ -31,12 +32,15 @@
".github",
]

PRIVATE_REPOS_DENYLIST = [
"automation-master",
"githubbot",
"ralph-loop-codex-marketplace",
"trusted-peer-setup",
]
def check_public_profile(text):
"""Check public links and an optional externally supplied private inventory."""
public_names = {name.casefold() for name in PUBLIC_REPOS}
links = re.findall(r'https://github\.com/dev-bricks/([^/\s)#?"<>]+)', text)
if any(name.casefold() not in public_names for name in links):
raise AssertionError("Profile contains an unlisted repository link")
private_names = re.split(r"[\s,;]+", os.environ.get("PROFILE_PRIVATE_REPO_DENYLIST", ""))
if any(name and name.casefold() in text.casefold() for name in private_names):
raise AssertionError("Profile contains a prohibited repository reference")

PUBLIC_ACTIVITY_DATES = {
".github": "2026-10-01",
Expand Down Expand Up @@ -94,13 +98,9 @@ def test_public_repo_inventory(file_contents):


def test_zero_private_leak_guard(file_contents):
"""Zero-leak invariant: ensure private repos are NEVER leaked into public profile surfaces."""
"""Check public links and any externally configured private-name guard."""
for filename in ["README.md", "profile/README.md", "profile/README_de.md", "llms.txt"]:
text = file_contents[filename]
for private_repo in PRIVATE_REPOS_DENYLIST:
assert private_repo not in text, (
f"SECURITY VIOLATION: Private repository '{private_repo}' leaked into public file {filename}!"
)
check_public_profile(file_contents[filename])


def test_check_timestamp_parity(file_contents):
Expand Down
Loading