Gardes nommées, reprise de revue : « nommée » jamais « déclarée », exclusions, registre du refus
gardes du contrat / conformite (pull_request) Successful in 17s
gardes du contrat / conformite (pull_request) Successful in 17s
Les trois corrections retenues de la revue extérieure d'openathle#275 — que j'avais amendées sur la branche d'une PR déjà fusionnée, donc jamais livrées : les champs disent ce qu'ils mesurent (nommee_par_parcours, _par_adr, _par_epreuve — un parcours peut porter la règle en prose sans nommer la classe) ; une absence n'est pas une règle (gardes_exclues, par motif — exclue = non observée) ; décider que non a un réceptacle (gardes_ecartees, registre de la juridiction, lu jamais écrit). Le journal porte ses motifs : la limite est dite là où la mesure s'écrit. La triade est mesurée : sans_epreuve. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
8670f57b16
commit
654042d0fa
+39
-8
@@ -190,29 +190,51 @@ function scanCitations(repo, files, ids) {
|
||||
function namedGuards(repo, cfg, files) {
|
||||
if (!Array.isArray(cfg.gardes_nommees) || cfg.gardes_nommees.length === 0) return null;
|
||||
const res = cfg.gardes_nommees.map(globToRegExp);
|
||||
const exclus = (Array.isArray(cfg.gardes_exclues) ? cfg.gardes_exclues : []).map(globToRegExp);
|
||||
const read = (p) => readFileSync(join(repo, p), 'utf8');
|
||||
const mdUnder = (dir) =>
|
||||
typeof dir === 'string' && existsSync(join(repo, dir)) ? walk(repo, join(repo, dir), []).filter((p) => p.endsWith('.md')) : [];
|
||||
const parcoursText = mdUnder(cfg.parcours).map(read).join('\n');
|
||||
const adrText = mdUnder(cfg.adr).map(read).join('\n');
|
||||
const tests = files.filter((f) => f.isTest).map((f) => read(f.path));
|
||||
// Le réceptacle du refus : ce que la juridiction a DÉCIDÉ d'écarter ou de
|
||||
// différer ne reparaît pas chaque nuit. Sans lui, la liste n'est jamais un
|
||||
// delta et le bruit devient un stresseur (ADR-061 §2.3). Le registre est un
|
||||
// fichier de la juridiction ; l'instrument le lit, il ne l'écrit jamais.
|
||||
const decisions = new Map();
|
||||
if (typeof cfg.gardes_ecartees === 'string' && existsFileAt(repo, cfg.gardes_ecartees)) {
|
||||
const reg = parseYaml(read(cfg.gardes_ecartees));
|
||||
for (const d of Array.isArray(reg) ? reg : []) if (d && typeof d.nom === 'string') decisions.set(d.nom, d);
|
||||
}
|
||||
const out = [];
|
||||
for (const f of files) {
|
||||
if (f.isTest || !res.some((re) => re.test(f.path))) continue;
|
||||
if (f.isTest || !res.some((re) => re.test(f.path)) || exclus.some((re) => re.test(f.path))) continue;
|
||||
const nom = f.path.split('/').pop().replace(/\.[^.]+$/, '');
|
||||
const re = new RegExp(`\\b${escapeRe(nom)}\\b`);
|
||||
const d = decisions.get(nom);
|
||||
const differee = d?.decision === 'differe' && typeof d.jusqu_au === 'string' && d.jusqu_au >= new Date().toISOString().slice(0, 10);
|
||||
out.push({
|
||||
nom,
|
||||
chemin: f.path,
|
||||
strate: f.stratum,
|
||||
dans_parcours: re.test(parcoursText),
|
||||
dans_adr: re.test(adrText),
|
||||
eprouve: tests.some((x) => re.test(x)),
|
||||
// NOMMÉE, jamais « déclarée » : un parcours peut porter la règle en
|
||||
// langue naturelle sans nommer la classe. L'instrument observe la
|
||||
// nomination — c'est sa limite, dite dans le nom des champs.
|
||||
nommee_par_parcours: re.test(parcoursText),
|
||||
nommee_par_adr: re.test(adrText),
|
||||
nommee_par_epreuve: tests.some((x) => re.test(x)),
|
||||
...(d?.decision === 'ecarte' ? { decision: 'ecarte', motif: d.motif ?? null } : {}),
|
||||
...(differee ? { decision: 'differe', jusqu_au: d.jusqu_au } : {}),
|
||||
});
|
||||
}
|
||||
return out.sort((a, b) => a.nom.localeCompare(b.nom));
|
||||
}
|
||||
|
||||
function existsFileAt(repo, p) {
|
||||
const st = statSync(join(repo, p), { throwIfNoEntry: false });
|
||||
return st !== undefined && st.isFile();
|
||||
}
|
||||
|
||||
function judge(hits, cfg) {
|
||||
const order = cfg.strates.map((s) => s.nom);
|
||||
const strata = [...new Set(hits.filter((h) => h.isTest).map((h) => h.stratum))]
|
||||
@@ -358,9 +380,18 @@ function emit(args, cfg, r) {
|
||||
? {}
|
||||
: {
|
||||
gardes_nommees: {
|
||||
// Ce que la mesure regarde, dit tel quel : les motifs. Ce qui n'y
|
||||
// correspond pas (require, objets-valeurs, contraintes SQL) est
|
||||
// invisible — la limite est dans le journal, pas seulement au README.
|
||||
motifs: cfg.gardes_nommees,
|
||||
...(Array.isArray(cfg.gardes_exclues) && cfg.gardes_exclues.length ? { exclus: cfg.gardes_exclues } : {}),
|
||||
total: r.gardes.length,
|
||||
sans_declaration: r.gardes.filter((g) => !g.dans_parcours).length,
|
||||
candidats: r.gardes.filter((g) => !g.dans_parcours),
|
||||
non_nommees_par_un_parcours: r.gardes.filter((g) => !g.nommee_par_parcours).length,
|
||||
sans_epreuve: r.gardes.filter((g) => !g.nommee_par_epreuve).length,
|
||||
ecartees: r.gardes.filter((g) => g.decision === 'ecarte').length,
|
||||
differees: r.gardes.filter((g) => g.decision === 'differe').length,
|
||||
// Les candidats du jour : non nommés par un parcours, ni écartés, ni différés.
|
||||
candidats: r.gardes.filter((g) => !g.nommee_par_parcours && g.decision === undefined),
|
||||
},
|
||||
}),
|
||||
reglage_empreinte: r.meta.reglageHash,
|
||||
@@ -382,8 +413,8 @@ function emit(args, cfg, r) {
|
||||
console.log(` à son étage : ${r.tally.domicilie} · renforcé : ${r.tally.renforce} · hors de son étage : ${r.tally.mal_domicilie} · jamais éprouvé : ${r.tally.aucun_locus}`);
|
||||
console.log(` constat(s) nouveau(x) : ${r.fresh.length}${args.dryRun ? '' : ` → ${cfg.sortie}`}`);
|
||||
if (r.gardes !== null) {
|
||||
const sans = r.gardes.filter((g) => !g.dans_parcours);
|
||||
console.log(` gardes nommées : ${r.gardes.length}, dont ${sans.length} qu'aucun parcours ne déclare${sans.length ? ' — ' + sans.map((g) => g.nom).join(', ') : ''}`);
|
||||
const cand = r.gardes.filter((g) => !g.nommee_par_parcours && g.decision === undefined);
|
||||
console.log(` gardes nommées : ${r.gardes.length} · candidates (non nommées par un parcours, ni écartées) : ${cand.length}${cand.length ? ' — ' + cand.map((g) => g.nom).join(', ') : ''}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user