feat: publish NIRO Gen5W research overview and reviewed source examples

This commit is contained in:
seo committed 2026-11-02 09:59:38 +09:00
commit ccad0ed9f3
23 files changed
+1279

No files matched your search

+87
View File
@@ -0,0 +1,87 @@
#!/usr/bin/env python3
"""Small publication gate, not a comprehensive security or licensing audit."""
import os
from pathlib import Path
import re
import subprocess
ROOT = Path(__file__).resolve().parents[1]
ALLOWED = {
".gitattributes", ".gitignore", "README.md", "RIGHTS.md", "LICENSE",
"SECURITY.md", "docs/ARCHITECTURE_KO.md", "docs/FEATURES_KO.md",
"docs/RESEARCH_KO.md", "docs/PUBLICATION_KO.md",
"telemetry/java/com/chaegeon/niro/HscanRpmDecoder.java",
"weather/java/com/chaegeon/niro/WeatherRefreshGate.java",
"weather/java/com/chaegeon/niro/WeatherRefreshCounters.java",
"backend/php/NiroMqttKeepalive.php", "backend/php/NiroRawSnappy.php",
"navigation/archived/v038/patch_nav_vehicle_speed_source.py",
"tests/java/HscanRpmDecoderTest.java", "tests/java/WeatherRefreshGateTest.java",
"tests/java/WeatherRefreshCountersTest.java", "tests/php/NiroMqttKeepaliveTest.php",
"tests/php/NiroRawSnappyTest.php", "tests/python/test_archived_speed_patch.py",
"tools/run_tests.py", "tools/check_publication.py",
}
PATTERNS = {
"private-key material": re.compile(rb"-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----"),
"GitHub credential candidate": re.compile(rb"\b(?:ghp_[A-Za-z0-9]{30,}|github_pat_[A-Za-z0-9_]{50,})\b"),
"literal bearer candidate": re.compile(rb"Bearer [A-Za-z0-9_./+~-]{24,}"),
"phone-number candidate": re.compile(rb"(?<![A-Za-z0-9])01[016789](?:[ -]?[0-9]){7,8}(?![A-Za-z0-9])"),
"private operational hostname": re.compile(rb"niro-gen5w\.tail[0-9a-z]+\.ts\.net|car\.chaegeon\.com"),
}
def git(*arguments):
# Use the executable, not a shell function or a machine-specific wrapper.
return subprocess.run(
["git", *arguments], cwd=ROOT, check=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, encoding="utf-8",
).stdout
def main():
errors = []
files = []
for directory, directories, names in os.walk(ROOT, followlinks=False):
base = Path(directory)
for name in list(directories):
target = base / name
relative = target.relative_to(ROOT).as_posix()
if relative == ".git":
directories.remove(name)
elif target.is_symlink():
errors.append("symlink directory: " + relative)
directories.remove(name)
for name in names:
path = base / name
relative = path.relative_to(ROOT).as_posix()
files.append(relative)
if path.is_symlink() or relative not in ALLOWED:
errors.append("file is not approved: " + relative)
continue
content = path.read_bytes()
if len(content) > 128 * 1024 or b"\0" in content:
errors.append("binary or unexpectedly large file: " + relative)
continue
try:
content.decode("utf-8")
except UnicodeDecodeError:
errors.append("non-UTF-8 file: " + relative)
for description, pattern in PATTERNS.items():
if pattern.search(content):
# Do not reveal a matched secret or personal value in output.
errors.append(description + ": " + relative)
if (ROOT / ".git").exists():
for relative in git("ls-files").splitlines():
if relative not in ALLOWED:
errors.append("unapproved tracked file: " + relative)
for email in set(git("log", "--all", "--format=%ae%n%ce").splitlines()):
if email and not email.endswith("@users.noreply.git.chaegeon.com"):
errors.append("commit author/committer email needs privacy review")
if errors:
raise SystemExit("Publication checks failed:\n" + "\n".join(sorted(set(errors))))
print("PASS: publication allowlist and basic privacy checks (" + str(len(files)) + " files)")
if __name__ == "__main__":
main()
+48
View File
@@ -0,0 +1,48 @@
#!/usr/bin/env python3
"""Run public synthetic tests locally; never contact a vehicle or network."""
import os
from pathlib import Path
import shutil
import subprocess
import sys
import tempfile
ROOT = Path(__file__).resolve().parents[1]
def run(*command):
environment = dict(os.environ, PYTHONDONTWRITEBYTECODE="1")
print("+ " + " ".join(str(part) for part in command), flush=True)
subprocess.run(command, cwd=ROOT, env=environment, check=True)
def main():
missing = [name for name in ("javac", "java", "php") if not shutil.which(name)]
if missing:
raise SystemExit("Required local tools are missing: " + ", ".join(missing))
run(sys.executable, "tools/check_publication.py")
run(sys.executable, "-B", "-m", "unittest", "discover", "-s", "tests/python", "-v")
sources = sorted(
list((ROOT / "telemetry/java").rglob("*.java"))
+ list((ROOT / "weather/java").rglob("*.java"))
+ list((ROOT / "tests/java").glob("*.java"))
)
with tempfile.TemporaryDirectory(prefix="niro-gen5w-public-tests-") as temporary:
run("javac", "-encoding", "UTF-8", "-d", temporary, *map(str, sources))
for name in (
"com.chaegeon.niro.HscanRpmDecoderTest",
"WeatherRefreshGateTest",
"com.chaegeon.niro.WeatherRefreshCountersTest",
):
run("java", "-cp", temporary, name)
for source in sorted((ROOT / "backend/php").glob("*.php")):
run("php", "-l", str(source))
for test in sorted((ROOT / "tests/php").glob("*Test.php")):
run("php", str(test))
print("PASS: all public synthetic test programs completed")
if __name__ == "__main__":
main()