fix(kyberforge): tell an unparsable Contributing-files block from an explicit (none)
parse_contributing_files documented that callers depend on None vs [], because a parse failure returning [] would silently disable the check. Only check 8 honoured it; checks 4/5 (skill-audit) and 3/4 (agent-audit) used a truthiness test, so an unreadable block disabled them without a word. Two live corpus entries were skipping this way. A sweep of all 32 sources.md found 134 entries, exactly 2 parsing to None, both in gitea-files: one heading carried an inline parenthetical that defeated both regexes, and one (none) was written without its leading bullet. Also pins EMPTY_SOURCE_KEYS_RE to the two indents parse_source_keys actually reads. agent-audit had no INFO tier at all, so it gains one rather than reporting a check that could not run as a FAIL. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EJJrm5YmacbwMdzZpXcoti
This commit is contained in:
@@ -22,7 +22,10 @@ Checks performed:
|
||||
0 source_keys present in agent pair but sources.md absent
|
||||
1 FILL IN: placeholders in sources.md
|
||||
2 source_keys in agent files → slug exists in sources.md
|
||||
3 Contributing files listed in sources.md exist on disk (plugin-root relative)
|
||||
3 Contributing files listed in sources.md exist on disk (plugin-root
|
||||
relative). An explicit '(none)' skips silently; a Contributing files block
|
||||
this parser cannot read is reported as an INFO saying checks 3 and 4 did
|
||||
not run, never skipped silently.
|
||||
4 Contributing files back-reference the parent slug in their source_keys
|
||||
5 Research doc field present and not placeholder
|
||||
EOF
|
||||
@@ -244,14 +247,31 @@ has_fail = False
|
||||
def emit_fail(desc, fpath, why, fix):
|
||||
global has_fail
|
||||
has_fail = True
|
||||
findings.append(("FAIL", desc, fpath, why, fix))
|
||||
findings.append(("FAIL", desc, fpath, why, fix, None))
|
||||
|
||||
# INFO does not set has_fail and does not change the exit code. It is for a
|
||||
# check that could not RUN — an unverified entry, not a broken one — and it
|
||||
# exists so that "did not run" is never spelled the same way as "passed".
|
||||
def emit_info(desc, fpath, note):
|
||||
findings.append(("INFO", desc, fpath, None, None, note))
|
||||
|
||||
def print_findings():
|
||||
for kind, desc, fpath, why, fix in findings:
|
||||
print(f"FAIL {desc} — {fpath}")
|
||||
print(f" Why: {why}")
|
||||
print(f" Fix: {fix}")
|
||||
print()
|
||||
for entry in findings:
|
||||
kind = entry[0]
|
||||
desc = entry[1]
|
||||
fpath = entry[2]
|
||||
why = entry[3]
|
||||
fix = entry[4]
|
||||
note = entry[5]
|
||||
if kind == "FAIL":
|
||||
print(f"FAIL {desc} — {fpath}")
|
||||
print(f" Why: {why}")
|
||||
print(f" Fix: {fix}")
|
||||
print()
|
||||
else:
|
||||
print(f"INFO {desc} — {fpath}")
|
||||
print(f" Note: {note}")
|
||||
print()
|
||||
|
||||
# --- Collect source_keys from agent pair ---
|
||||
def get_source_keys_from_file(fpath):
|
||||
@@ -321,9 +341,24 @@ for fpath, keys in [(agent_file, given_keys)]:
|
||||
|
||||
# --- Checks 3, 4, 5: Per-slug checks in sources.md ---
|
||||
for slug in parse_h2_slugs(sources_content):
|
||||
# Check 3: Contributing files exist (paths relative to plugin root)
|
||||
# Checks 3 and 4: Contributing files exist (paths relative to plugin root),
|
||||
# and back-reference the slug. `[]` and None are NOT the same answer here.
|
||||
# `[]` is the author writing "(none)" — there is nothing to check and the
|
||||
# skip is correct. None is a Contributing-files block this parser cannot
|
||||
# read, and skipping THAT silently disables both checks on the one entry
|
||||
# least likely to be right, which is the failure mode
|
||||
# parse_contributing_files' own docstring warns about. Say so out loud.
|
||||
cf_files = parse_contributing_files(sources_content, slug)
|
||||
if cf_files:
|
||||
if cf_files is None:
|
||||
emit_info(
|
||||
f"Contributing-file checks skipped for '{slug}' — the Contributing files block could not be parsed",
|
||||
f"sources.md (## {slug})",
|
||||
f"The '## {slug}' entry has no Contributing files list this parser can read — a missing field, a bare heading, '*' bullets, a numbered list, or prose all read as unparsable rather than as an empty declaration. "
|
||||
f"Checks 3 and 4 did not run for this slug, so nothing verified that its contributing files exist or name it back. "
|
||||
f"Write the value as '- **Contributing files:** <comma-separated paths>', or as a '**Contributing files:**' heading followed by '- ' bullets — "
|
||||
f"or record '(none)' if this source contributed no files."
|
||||
)
|
||||
elif cf_files:
|
||||
for cf_rel in cf_files:
|
||||
cf_abs = os.path.join(plugin_root, cf_rel)
|
||||
if not os.path.isfile(cf_abs):
|
||||
|
||||
Reference in New Issue
Block a user