tawasuyu

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 1574Shell 204Rust 111Markdown 993763 Definitions

⎇ 91496007ca9d3e711993441c23170bd1470e1665 scripts/harkaq/harkaq-trace-norm.py Python · 71 lines · 2.9 KB History Who touched what raw

harkaq-trace: la traza POSITIVA de la clausura (plan-freebsd T1.1-T1.2, prior art filemon/META MODE) 91496007c · sergio ·

1#!/usr/bin/env python3
2"""harkaq-trace-norm — canoniza la traza cruda de harkaq-trace (plan-freebsd T1.2).
3
4    harkaq-trace-norm.py <traza-cruda> [--store <dir>] [--drop <prefijo>]... [--resumen]
5
6Las reglas de normalización son la parte que FreeBSD tardó años en iterar (los `.meta` de
7META MODE): el ruido no se CALLA, se clasifica con reglas explícitas — D3 aplica acá igual
8que en el verdict. Reglas:
9
10  1. DROP por prefijo: /proc /sys /dev /tmp /out /src (el build escribe /out y lee /src por
11     contrato; lo interesante es lo demás). Ampliable con --drop.
12  2. DEDUPE + ORDEN ESTABLE: la traza cruda trae un evento por open(); el mismo path N veces
13     no es señal (el orden de llegada tampoco: readdir no garantiza orden — la lección
14     número uno de META MODE). Salida: paths únicos, ordenados.
15  3. ATRIBUCIÓN por dep (--store): un path store/<hash>-<nombre>/resto se atribuye a la dep
16     <nombre>. Con --resumen emite el conteo por dep — la señal de PODA (T1.4): una dep
17     declarada con 0 toques es grasa de la clausura.
18
19El sellado (T1.3) NO es de este script: la salida canónica es determinista a propósito
20(orden estable, sin timestamps) para que `b3sum` del worker la selle tal cual y viaje junto
21al of_tree. Un script canoniza, el store sella — cada pieza tonta en lo suyo.
22"""
23import argparse
24import re
25import sys
26from collections import Counter
27from pathlib import Path
28
29DROP_DEFAULT = ["/proc", "/sys", "/dev", "/tmp", "/out", "/src", "/run"]
30
31
32def main():
33    ap = argparse.ArgumentParser()
34    ap.add_argument("traza")
35    ap.add_argument("--store", default=None,
36                    help="raíz del store para atribuir paths a deps (store/<hash>-<nombre>/…)")
37    ap.add_argument("--drop", action="append", default=[],
38                    help="prefijo adicional a descartar (repetible)")
39    ap.add_argument("--resumen", action="store_true",
40                    help="emite conteo por dep en vez de la lista canónica")
41    args = ap.parse_args()
42
43    drops = DROP_DEFAULT + args.drop
44    store = str(Path(args.store).resolve()) if args.store else None
45    # store/<hash-hex>-<nombre>/… — el nombre puede traer guiones; el hash no.
46    re_dep = re.compile(re.escape(store) + r"/[0-9a-f]{16,}-([^/]+)/") if store else None
47
48    unicos = set()
49    por_dep = Counter()
50    with open(args.traza) as f:
51        for linea in f:
52            p = linea.strip()
53            if not p or any(p == d or p.startswith(d + "/") for d in drops):
54                continue
55            if p not in unicos and re_dep:
56                m = re_dep.match(p)
57                if m:
58                    por_dep[m.group(1)] += 1
59            unicos.add(p)
60
61    if args.resumen:
62        for dep, n in sorted(por_dep.items()):
63            print(f"{n:6d}  {dep}")
64    else:
65        for p in sorted(unicos):
66            print(p)
67    return 0
68
69
70if __name__ == "__main__":
71    sys.exit(main())