Skip to content

Commit b886797

Browse files
fix: harden community gate — discover meta-less dirs, broaden secret scan, utf-8, escape table pipes
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 6279b00 commit b886797

6 files changed

Lines changed: 71 additions & 11 deletions

File tree

community/scripts/build_index.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,23 +47,33 @@ def load_entries(community_dir: Path) -> list[dict]:
4747
return entries
4848

4949

50+
def _escape_pipes(value: str) -> str:
51+
return value.replace("|", "\\|")
52+
53+
5054
def _links_cell(links: dict) -> str:
51-
parts = [f"[{label}]({url})" for label, url in links.items() if str(url).startswith("http")]
55+
parts = [
56+
f"[{_escape_pipes(str(label))}]({url})"
57+
for label, url in links.items()
58+
if str(url).startswith("http")
59+
]
5260
return "<br>".join(parts) if parts else ""
5361

5462

5563
def _row(entry: dict) -> str:
56-
project = f"[{entry['title']}]({entry['slug']}/)"
64+
project = f"[{_escape_pipes(entry['title'])}]({entry['slug']}/)"
5765
author = (
58-
f"[@{entry['author']}](https://github.com/{entry['author']})" if entry["author"] else ""
66+
f"[@{_escape_pipes(entry['author'])}](https://github.com/{entry['author']})"
67+
if entry["author"]
68+
else ""
5969
)
60-
tags = ", ".join(str(t) for t in entry["tags"])
70+
tags = _escape_pipes(", ".join(str(t) for t in entry["tags"]))
6171
hosted = "hosted" if entry["hosted"] else ""
6272
cells = [
6373
project,
6474
author,
65-
entry["description"],
66-
entry["opik_platform"],
75+
_escape_pipes(entry["description"]),
76+
_escape_pipes(entry["opik_platform"]),
6777
_links_cell(entry["links"]),
6878
hosted,
6979
tags,
@@ -83,12 +93,14 @@ def render_index(entries: list[dict]) -> str:
8393

8494

8595
def write_index(community_dir: Path) -> None:
86-
(community_dir / "README.md").write_text(render_index(load_entries(community_dir)))
96+
(community_dir / "README.md").write_text(
97+
render_index(load_entries(community_dir)), encoding="utf-8"
98+
)
8799

88100

89101
def check_index(community_dir: Path) -> bool:
90102
readme = community_dir / "README.md"
91-
current = readme.read_text() if readme.is_file() else ""
103+
current = readme.read_text(encoding="utf-8") if readme.is_file() else ""
92104
return current == render_index(load_entries(community_dir))
93105

94106

community/scripts/check_entry.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@
1717

1818

1919
def discover_entries(community_dir: Path) -> list[Path]:
20-
entries = [
20+
return [
2121
child
2222
for child in sorted(community_dir.iterdir())
23-
if child.is_dir() and child.name not in RESERVED_DIRS and (child / "meta.yaml").is_file()
23+
if child.is_dir() and child.name not in RESERVED_DIRS
2424
]
25-
return entries
2625

2726

2827
def check_entry(entry: Path) -> list[str]:

community/scripts/entry_rules.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ def validate_proof(entry: Path) -> list[str]:
121121
_FOLDER_NAME_RE = re.compile(r"^[a-z0-9]+(?:_[a-z0-9]+)+$")
122122
_SECRET_PATTERNS = [
123123
re.compile(r"sk-ant-[A-Za-z0-9_-]{20,}"),
124+
re.compile(r"sk-(?:proj|svcacct)-[A-Za-z0-9_-]{20,}"),
124125
re.compile(r"sk-[A-Za-z0-9]{20,}"),
125126
re.compile(r"""OPIK_API_KEY\s*[=:]\s*["'][^"']+["']"""),
126127
]

community/scripts/tests/test_build_index.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,20 @@ def test_check_index_detects_stale(tmp_path: Path):
4242
write_entry(tmp_path, slug="jane_agent")
4343
(tmp_path / "README.md").write_text("# stale\n")
4444
assert check_index(tmp_path) is False
45+
46+
47+
def test_pipe_in_description_is_escaped_in_table_row(tmp_path: Path):
48+
write_entry(
49+
tmp_path,
50+
slug="jane_agent",
51+
meta={"description": "Handles A | B and C | D cases"},
52+
)
53+
out = render_index(load_entries(tmp_path))
54+
table_line = next(line for line in out.splitlines() if line.startswith("| [Real"))
55+
assert "A \\| B and C \\| D" in table_line
56+
# Stripping the leading/trailing "| " and splitting on " | " must yield
57+
# exactly 7 columns; escaped pipes must not be miscounted as separators.
58+
stripped = table_line.strip()
59+
assert stripped.startswith("| ") and stripped.endswith(" |")
60+
inner = stripped[2:-2]
61+
assert len(inner.split(" | ")) == 7

community/scripts/tests/test_check_entry.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,29 @@ def test_discover_skips_reserved_dirs(tmp_path: Path):
2828
assert found == {"jane_agent"}
2929

3030

31+
def test_discover_includes_dir_without_meta_yaml(tmp_path: Path):
32+
entry = write_entry(tmp_path, slug="no_meta_here")
33+
(entry / "meta.yaml").unlink()
34+
found = {p.name for p in discover_entries(tmp_path)}
35+
assert "no_meta_here" in found
36+
37+
38+
def test_check_entry_flags_missing_meta_yaml(tmp_path: Path):
39+
entry = write_entry(tmp_path, slug="no_meta_here")
40+
(entry / "meta.yaml").unlink()
41+
errors = check_entry(entry)
42+
assert any("missing meta.yaml" in e for e in errors)
43+
44+
45+
def test_main_no_args_returns_one_when_entry_missing_meta_yaml(tmp_path: Path, monkeypatch):
46+
entry = write_entry(tmp_path, slug="no_meta_here")
47+
(entry / "meta.yaml").unlink()
48+
import check_entry as check_entry_module
49+
50+
monkeypatch.setattr(check_entry_module, "COMMUNITY_DIR", tmp_path)
51+
assert main([]) == 1
52+
53+
3154
def test_main_returns_zero_for_valid_entry(tmp_path: Path):
3255
entry = write_entry(tmp_path)
3356
assert main([str(entry)]) == 0

community/scripts/tests/test_entry_rules.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,14 @@ def test_hardcoded_key_is_flagged(tmp_path: Path):
158158
assert any("hardcoded" in e.lower() or "key" in e.lower() for e in validate_no_secrets(entry))
159159

160160

161+
def test_sk_proj_key_is_flagged(tmp_path: Path):
162+
entry = write_entry(
163+
tmp_path,
164+
code={"app.py": 'client = OpenAI(api_key="sk-proj-abcdefghijklmnopqrstuvwxyz012345")\n'},
165+
)
166+
assert any("hardcoded" in e.lower() or "key" in e.lower() for e in validate_no_secrets(entry))
167+
168+
161169
def test_hosted_without_opik_usage_is_error(tmp_path: Path):
162170
entry = write_entry(
163171
tmp_path,

0 commit comments

Comments
 (0)