Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
7e1d28e
feat: add scoped command policy and atomic execution budgets
senamakel Oct 10, 2026
b8b903a
fix(command): preserve shell grammar and legacy execution admission
senamakel Oct 10, 2026
41d1c69
fix: scan all heredocs and attached redirect targets
senamakel Oct 10, 2026
9257240
fix: preserve POSIX heredoc lexical boundaries
senamakel Oct 10, 2026
a2a803f
refactor: separate heredoc header lexical state
senamakel Oct 10, 2026
e69a538
fix: retain unsupported expanded heredoc continuations
senamakel Oct 10, 2026
1d32e20
fix: use POSIX blanks for heredoc token boundaries
senamakel Oct 10, 2026
43a641e
Merge remote-tracking branch 'origin/main' into security-complete-7328
senamakel Oct 10, 2026
353d34a
feat: add bounded native redaction and semantic scans
senamakel Oct 10, 2026
8dcf880
style: satisfy strict redactor clippy checks
senamakel Oct 10, 2026
ff43422
fix: close structured credential and endpoint redaction gaps
senamakel Oct 10, 2026
e57de62
fix(redact): detect direct credential transfers without determiners
senamakel Oct 10, 2026
f85423a
feat(egress): implement scoped native URL and privacy authorization
senamakel Oct 10, 2026
87d909f
fix(egress): close reserved address privacy and lease review gaps
senamakel Oct 10, 2026
86caec9
chore: pin reviewed authenticated TinyBus callback SDK
senamakel Oct 10, 2026
cebc2ec
fix: authorize native policy calls with pinned broker peer
senamakel Oct 10, 2026
5e5e172
feat: add exact audit callbacks and restricted Unix sink
senamakel Oct 10, 2026
fc24e2a
fix: bound authoritative audit journal and native worker waits
senamakel Oct 10, 2026
d618792
fix(sdk): consume reviewed unique-peer attestation
senamakel Oct 10, 2026
40ce807
fix(audit): bind permission decisions to exact durable events
senamakel Oct 10, 2026
aef4a5b
fix(audit): consume reviewed Windows SDK fixture admission
senamakel Oct 10, 2026
de6bc9a
test(audit): exercise protected Windows journal and blocked rotation
senamakel Oct 10, 2026
6126bd3
test(audit): cover immutable callbacks and native failure semantics
senamakel Oct 10, 2026
d5d1f6a
feat(audit): support protected preprovisioned Windows journal
senamakel Oct 10, 2026
a1e30a8
test: diagnose Windows audit validation stages
senamakel Oct 10, 2026
bac80f2
chore: consume reviewed TinyBus attestation scope fix
senamakel Oct 10, 2026
7854e38
test: exercise native audit callback failure and race paths
senamakel Oct 10, 2026
140d146
fix: validate protected Windows DACL control tokens
senamakel Oct 10, 2026
6f32797
test: trigger Windows rotation and reject unsafe storage
senamakel Oct 10, 2026
b280629
test: probe Windows directory share access accounting
senamakel Oct 10, 2026
2094c5b
test: exercise audit recovery across process crashes
senamakel Oct 10, 2026
94b0d31
fix: retain share-enforced Windows directory handles
senamakel Oct 11, 2026
bd36f03
test(audit): verify loaded native journal and ordinary account isolation
senamakel Oct 11, 2026
19d9244
test(audit): extend native permission and ACL recovery acceptance
senamakel Oct 11, 2026
0f86b31
test: diagnose ordinary Windows account failure stages
senamakel Oct 11, 2026
1c3daf5
test: prove ordinary account reaches audit namespace
senamakel Oct 11, 2026
a22e310
test: diagnose credential launch native error chain
senamakel Oct 11, 2026
f037896
test: classify credential launch errors without raw diagnostics
senamakel Oct 11, 2026
fe2be6f
fix: deny null DACL before native ACL accessor
senamakel Oct 11, 2026
6fdb6f6
test: keep account helper script outside function lint budget
senamakel Oct 11, 2026
c85b80d
test: verify credential parser and independent cleanup
senamakel Oct 11, 2026
4152e9c
test: isolate credentialed command length limit
senamakel Oct 11, 2026
2b94b79
fix: launch ordinary audit helper with bounded stdin command
senamakel Oct 11, 2026
99f7873
test: require every native ordinary account security phase
senamakel Oct 11, 2026
7935fd9
test: diagnose native helper stdin parse and invocation
senamakel Oct 11, 2026
0eca18f
test(audit): classify native child stdin encoding without content
senamakel Oct 11, 2026
c494cd5
test(audit): deliver full foreign-account script as UTF-8 without BOM
senamakel Oct 11, 2026
118f7b2
Fix native manifest audit capability inventory
senamakel Oct 11, 2026
c9810ba
test(audit): distinguish bootstrap and native worker failures
senamakel Oct 11, 2026
e932197
fix(audit): release append locks before inherited descriptors close
senamakel Oct 11, 2026
3bff76f
test(audit): classify child command and receipt failure locations
senamakel Oct 11, 2026
db15759
test(audit): identify invisible transport characters and isolate disk…
senamakel Oct 11, 2026
334496f
fix(audit): configure original redirected writer before process start
senamakel Oct 11, 2026
9dfeb06
test(audit): diagnose foreign helper identity environment
senamakel Oct 11, 2026
cd47860
fix(audit): bind fixture context to credentialed helper
senamakel Oct 11, 2026
20a251b
test(audit): separate native durability fixture from short deadline
senamakel Oct 11, 2026
efd0b61
test(audit): diagnose Windows private-file loop failures
senamakel Oct 11, 2026
c8408c4
test(audit): attempt native rename before checking denial
senamakel Oct 11, 2026
1ceda13
test(audit): diagnose namespace rename failures
senamakel Oct 11, 2026
68f9053
test(audit): recognize exact native directory access denial
senamakel Oct 11, 2026
9ae745e
Diagnose native Windows audit namespace installation
senamakel Oct 11, 2026
dc2ce40
Classify sanitized native ACL installer failures
senamakel Oct 11, 2026
27f357e
Persist the native fixture ACL without Set-Acl
senamakel Oct 11, 2026
e8ee29d
test: expose bounded native audit initialization diagnostics
senamakel Oct 11, 2026
cf78c3e
test: pin Windows installer and new file ownership
senamakel Oct 11, 2026
5a8a6eb
Fix Windows audit owner checkpoint setup and diagnostics
senamakel Oct 11, 2026
10de9f8
Allow create-new access validation in Windows audit fixture
senamakel Oct 11, 2026
b85829e
Bind newly created audit file ownership before verification
senamakel Oct 11, 2026
a86c7be
test(audit): prove child authority before ancestor denial
senamakel Oct 11, 2026
85839ec
fix(audit): bind Windows test journals to current user
senamakel Oct 11, 2026
88d0c52
ci: enforce native Windows audit coverage
senamakel Oct 11, 2026
89cf140
fix(ci): reject missing native executable coverage
senamakel Oct 11, 2026
20fde37
test(audit): classify ordinary-account startup failures
senamakel Oct 11, 2026
f52420d
test(audit): classify PowerShell startup error records
senamakel Oct 11, 2026
36ca060
test(audit): normalize Windows PowerShell fixture module paths
senamakel Oct 11, 2026
946a0cc
fix(audit): export native LCOV and cover Windows callbacks
senamakel Oct 11, 2026
1907aaa
fix: remove needless hashes from Windows callback fixture
senamakel Oct 11, 2026
a8a7a62
test: expose native audit generation race diagnostics
senamakel Oct 11, 2026
f43fea4
Fix native coverage Git diff UTF-8 decoding
senamakel Oct 11, 2026
a404f07
feat: implement durable exact approvals and authenticated callbacks
senamakel Oct 11, 2026
f5be5b9
fix: reconcile reusable grants and reclaim durable creation retries
senamakel Oct 11, 2026
7d0161b
fix: audit reentrant durable winners before returning permission
senamakel Oct 11, 2026
f1c5756
test: pin approval fixture Windows drive paths
senamakel Oct 11, 2026
d6235da
fix: preserve approval fixture drive paths on Windows
senamakel Oct 11, 2026
31a2f3d
feat: score verified approvals with bounded native Jev
senamakel Oct 11, 2026
09207f1
fix: preserve judge wire defaults under strict clippy
senamakel Oct 11, 2026
03d5e36
fix(approval): recheck reusable grants and shrink judge caches
senamakel Oct 11, 2026
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
217 changes: 217 additions & 0 deletions .github/scripts/check-native-coverage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
#!/usr/bin/env python3
"""Enforce native file and changed-line coverage without dependencies.

JSON supplies per-file executable counts; LCOV supplies changed executable lines.
Only exact checkout-relative crate paths are admitted. Both Windows audit sources
must be instrumented on Windows; Unix runners require the native journal and sink.
"""
import argparse
import json
import os
import re
import subprocess
import sys
from pathlib import Path

REQUIRED = (
'crates/tinysecurity-audit/src/windows.rs',
'crates/tinysecurity-audit/src/windows_acl.rs',
)

UNIX_REQUIRED = (
'crates/tinysecurity-audit/src/sink.rs',
'crates/tinysecurity-audit/src/journal.rs',
'crates/tinysecurity-audit/src/rotation.rs',
)


def required_sources(platform):
"""Select actual native sources, never require disabled Windows code on Unix."""
return REQUIRED if platform == 'windows' else UNIX_REQUIRED


def relative_source(filename, root):
"""Return a crate path under the exact checkout, or None for other files."""
filename = filename.replace('\\', '/')
root = root.replace('\\', '/').rstrip('/')
# Windows drive paths are case insensitive; POSIX paths are not.
windows = bool(re.match(r'^[A-Za-z]:/', root))
candidate = filename.casefold() if windows else filename
prefix = (root.casefold() if windows else root) + '/'
if not candidate.startswith(prefix):
return None
relative = filename[len(prefix):]
if windows:
relative = relative.casefold()
parts = relative.split('/')
if '\x00' in relative or any(part in ('', '.', '..') for part in parts):
raise ValueError(f'invalid checkout source path: {filename}')
if relative.startswith('vendor/'):
return None
if not relative.startswith('crates/') or not relative.endswith('.rs'):
raise ValueError(f'unknown checkout source path: {filename}')
return relative


def check_files(report, root, minimum, platform="windows"):
"""Reject absent, empty, inconsistent, or below-threshold source reports."""
files = {}
for datum in report['data']:
for entry in datum['files']:
name = relative_source(entry['filename'], root)
if name is None:
continue
lines = entry['summary']['lines']
count, covered = lines['count'], lines['covered']
if (type(count) is not int or type(covered) is not int
or count < 0 or covered < 0 or covered > count):
raise ValueError(f'invalid executable counts: {name}')
counts = (covered, count)
if name in files and files[name] != counts:
raise ValueError(f'conflicting duplicate source: {name}')
files[name] = counts
for name in required_sources(platform):
if name not in files:
raise ValueError(f'missing required {platform.title()} source: {name}')
if files[name][1] == 0:
raise ValueError(f'no executable lines in required {platform.title()} source: {name}')
for name, (covered, count) in sorted(files.items()):
if count and covered * 100 < minimum * count:
raise ValueError(f'{name}: {covered}/{count} lines below {minimum}%')
return files


def parse_lcov(report, root):
"""Normalize LCOV SF records and merge repeated instrumentation counts."""
files = {}
current = None
for record in report.splitlines():
if record.startswith('SF:'):
current = relative_source(record[3:], root)
if current is not None:
files.setdefault(current, {})
elif record.startswith('DA:') and current is not None:
fields = record[3:].split(',')
if len(fields) not in (2, 3):
raise ValueError(f'invalid LCOV line record: {current}')
line, count = int(fields[0]), int(fields[1])
if line <= 0 or count < 0:
raise ValueError(f'invalid LCOV line: {current}')
files[current][line] = files[current].get(line, 0) + count
elif record == 'end_of_record':
current = None
return files


def production_source(name):
"""Tests are not production changes; their JSON file coverage still applies."""
return (name.startswith('crates/') and '/src/' in name
and name.endswith('.rs') and not name.endswith('_tests.rs'))


def changed_lines(diff):
"""Extract added/modified production line ranges from git's unified=0 diff."""
files = {}
current = None
for line in diff.splitlines():
if line.startswith('+++ '):
name = line[4:]
if not name.startswith('b/') and name != '/dev/null':
raise ValueError('unrecognized git diff source path')
current = name[2:] if name.startswith('b/') else None
if current is not None and any(part in ('', '.', '..') for part in current.split('/')):
raise ValueError('invalid git diff source path')
if current is not None and not production_source(current):
current = None
elif current is not None and line.startswith('@@ '):
match = re.match(r'@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@', line)
if match is None:
raise ValueError('invalid git diff hunk')
first = int(match[1])
count = int(match[2]) if match[2] is not None else 1
if count:
files.setdefault(current, set()).update(range(first, first + count))
return files


def check_changed(lines, changed, minimum, compiled, platform="windows"):
"""Cross-check compiled production admission before measuring changed lines.

JSON is the native compilation inventory: platform-disabled sources are
absent, and declaration-only sources have zero executable lines. Neither
requires LCOV. Every admitted executable production source does, even when
unchanged, so missing instrumentation cannot silently shrink the gate.
"""
for name in required_sources(platform):
if not lines.get(name):
raise ValueError(f'no measured changed or executable LCOV lines: {name}')
for name, (_, count) in compiled.items():
if production_source(name) and count and not lines.get(name):
raise ValueError(f'missing executable LCOV source: {name}')
for name, executable in lines.items():
if production_source(name) and executable and (name not in compiled or not compiled[name][1]):
raise ValueError(f'LCOV source absent from executable JSON inventory: {name}')
# Sources disabled on this platform and declaration-only files supply no
# executable denominator. Inventory consistency above still runs first.
changed = {name: changed_set for name, changed_set in changed.items()
if name in compiled and compiled[name][1]}
if not changed:
return None
for name in required_sources(platform):
if name not in changed:
continue
measured = set(lines.get(name, {})) & changed.get(name, set())
if not measured:
raise ValueError(f'no measured changed executable lines: {name}')
covered = total = 0
for name, changed_set in changed.items():
for line in changed_set & set(lines.get(name, {})):
total += 1
covered += lines[name][line] > 0
if not total:
raise ValueError('no measured changed executable lines in workspace')
if covered * 100 < minimum * total:
raise ValueError(f'changed lines: {covered}/{total} below {minimum}%')
return covered, total


def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--json', required=True)
parser.add_argument('--lcov', required=True)
parser.add_argument('--base', required=True, help='canonical PR base commit/ref')
parser.add_argument('--root', default=str(Path.cwd()))
parser.add_argument('--platform', choices=('windows', 'linux', 'macos'), default='windows')
args = parser.parse_args()
files = check_files(json.loads(Path(args.json).read_text(encoding='utf-8')), args.root, 90, args.platform)
print('File\tLine coverage\tCovered lines\tCoverable lines')
for name, (covered, count) in sorted(files.items()):
if count:
print(f'{name}\t{covered * 100 / count:.2f}%\t{covered}\t{count}')
# Decode after byte capture: Windows text-reader threads can lose stdout
# on a decoding failure. Strict UTF-8 errors must reject the gate instead.
diff = subprocess.run(
['git', '-c', 'core.quotePath=false', 'diff', '--no-ext-diff', '--no-renames',
'--unified=0', args.base, 'HEAD', '--', 'crates/'],
cwd=args.root, check=True, capture_output=True,
).stdout.decode('utf-8')
changed = changed_lines(diff)
lcov = parse_lcov(Path(args.lcov).read_text(encoding='utf-8'), args.root)
result = check_changed(lcov, changed, 80, files, args.platform)
if result is None:
print('No changed compiled executable sources relative to canonical base; file gate passed.')
return
covered, total = result
print(f'Changed executable lines: {covered}/{total} ({covered * 100 / total:.2f}%)')
if os.environ.get('GITHUB_STEP_SUMMARY'):
with open(os.environ['GITHUB_STEP_SUMMARY'], 'a', encoding='utf-8') as summary:
summary.write(f'Native {args.platform} coverage: {len(files)} source reports; '
f'changed executable lines {covered}/{total}.\n')


if __name__ == '__main__':
try:
main()
except (ValueError, KeyError, OSError, subprocess.CalledProcessError) as error:
print(f'native coverage rejected: {error}', file=sys.stderr)
sys.exit(1)
Loading
Loading