Skip to content

feat(ctf): multi-event corpus ingestion and 30 new tier-B challenges - #29

Closed
log0u7 wants to merge 4 commits into
mainfrom
feat/ctf-corpus-scale-v2
Closed

log0u7 wants to merge 4 commits into
mainfrom
feat/ctf-corpus-scale-v2

Conversation

@log0u7

@log0u7 log0u7 commented Oct 26, 2026

Copy link
Copy Markdown
Owner

Summary

  • ingest generalizes across CTF-Archives events (Zeekr 2026-09-19, WQB 2026-09-04, CCB 2026-09-13): challenges resolve to their content root and deduplicate by that root (symlink-cycle guarded), longest directory name = canonical challenge name.
  • Statement matching strips the hex-hash suffix of release dir names (all 29 WQB/CCB statements now extract; verified on cold_forge + ticketsage).
  • 30 new tier-B challenges: WQB 27 slots (incl. SilentConfig tar.gz), CCB 3. Statements in Chinese, flag format only, writeups never embedded.
  • Regression guards: case-id charset/uniqueness asserts, manifest-vs-cases consistency test (the orphan class found by review), statement-less fallback test, symlink-cycle test.
  • The statement-less incident challenge stays OUT of the corpus (gitleaks trips on its fictional UUID; its tar remains in the local store).

Issue for this PR

N/A

Checklist

  • Conventional Commits
  • Tests added (test_ctf_ingest.py: 6 tests, corpus fixtures across the three extraction layouts)
  • 473 tests + lint + mypy green locally

ingest generalizes across CTF-Archives events (Zeekr 2026-09-19, WQB
2026-09-04, CCB 2026-09-13): extraction layouts vary per zip (wrappers,
nesting), so challenges resolve to their content root and deduplicate
by that root with the longest directory name as canonical name. 30 new
tier-B challenges from the WQB and CCB dumps (statements in Chinese,
flag format only, writeups never embedded).

New totals: 58 corpus cases (6 lictor + 6 ROP Emporium verified tier,
46 tier-B across three events).
- _statement_for strips the hex-hash suffix of release dir names before
  matching README headings (all 29 WQB/CCB statements were falling back
  to the bare directory name).
- six stale case files removed (earlier-run artifacts absent from the
  regenerated manifest).
- content-root dedup keys on resolve() so symlinked wrappers merge;
  revisited resolved paths stop the descent (cycle guard).
- case ids: ASCII-fold slug, uniqueness + charset asserts, and a
  manifest/cases consistency check in main().
- SilentConfig tar.gz extracted into the corpus (27 WQB slots).
…d regression guards

The incident case (no README statement, synthetic UUID tripping
gitleaks) leaves the corpus - its tar stays in the store for a future
allowlisted re-ingest. The 32 orphan case files from superseded slug
generations are removed: the committed manifest now matches the
committed cases exactly (regression test added). Statement-less
challenges fall back to the canonical directory name (test added).
@log0u7

log0u7 commented Oct 26, 2026

Copy link
Copy Markdown
Owner Author

Superseded by #30 (same tree): CI trigger drop anomaly on follow-up pushes.

@log0u7 log0u7 closed this Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant