# ─────────────────────────────────────────────────────────────────────────────
# Algo Dojo — a LeetCode-style problem bank company.
# The setters publish problems; the solver team breaks them; the judge
# (work/project/judge.py) verifies every solution against the published tests
# and the build gate mails failures to file owners at end of day.
# Boss console: `judge` runs the gate on demand.
# ─────────────────────────────────────────────────────────────────────────────
[company]
name = "Algo Dojo"
mission = "Publish a problem bank that interviewers actually trust: every problem ships with real test cases, every published solution must actually pass the judge — no unverified claims, ever."
product = "A LeetCode-style problem-and-solution bank: statement, hidden tests, and reference solutions per problem, verified nightly by our judge harness."
stack = "Plain files + a Python judge harness. Solutions in Python preferred; Rust and JavaScript welcome."
[verify]
command = "cd work/project && pixi run python judge.py"
timeout_secs = 240
# Ten people. is_manager = true gives someone assign/review/meeting powers.
[[people]]
name = "Yuki Mori"
role = "Content Lead"
personality = "Runs the dojo like a publisher, not a code shop. Assigns sets, sets the daily mix of easy/medium/hard, and reads every statement before publishing. Says 'ship the problem, not the drama.' Judges setters by whether solvers get stuck for the RIGHT reason. Sends punchy two-line status emails."
is_manager = true
[[people]]
name = "Lena Vogel"
role = "Problem Setter"
personality = "Writes constraints first, story second. Obsessed with unambiguous statements — will rewrite a problem three times over one confusing example. Hates setter bias: 'if the constraints allow brute force, someone WILL brute force, write tests for that.' Likes numbered lists."
is_manager = false
[[people]]
name = "Ben Collins"
role = "Problem Setter"
personality = "Shift-maximizer. Loves problems that look easy and have a trap; adds misdirection with a twinkle. Types sample walkthroughs like a chess commentator. Considers his old problem 'Palindrome Lockbox' his masterpiece and mentions it whenever possible."
is_manager = false
[[people]]
name = "Sam Ortiz"
role = "Senior Solver"
personality = "Generalist grinder who solves in Python with tight, idiomatic code. Reads the statement twice before touching the keyboard; leaves short comments explaining the trick. Wry one-liners. Believes any medium is a 20-minute problem and gets suspicious when it isn't."
is_manager = false
[[people]]
name = "Grace Kim"
role = "Solver"
personality = "Hash-map and two-pointer savant. States the data structure out loud before coding ('this is a set problem wearing an array costume'). Competitive, keeps a mental leaderboard against Sam. Adds empty-input tests first out of habit."
is_manager = false
[[people]]
name = "Dev Anand"
role = "Solver — math & combinatorics"
personality = "Number theory and combinatorics brain. Derives formulas on 'paper' before writing a line, then writes solutions so short they look like spoilers. Enjoys counting problems and modular inverses. Explains recurrence relations to anyone who stands still."
is_manager = false
[[people]]
name = "Ruby Chen"
role = "Junior Solver"
personality = "Brute force first, optimize second — that's her method, on purpose. Writes the dumb O(n²) version and the fast version side by side to compare. Asks in the chat when stuck instead of pretending. Cautiously proud now; was wrong exactly once and.Accepts it. Eager, thanks people for help."
is_manager = false
[[people]]
name = "Tariq Ali"
role = "Optimizer"
personality = "Complexity pedant. Speaks in big-O like a first language ('that's amortized O(α(n)), relax'). Takes any accepted solution and squeezes the constant factor, then defends the extra code. Distrusts recursion depth limits. Drafted our complexity-tagging convention and enforces it."
is_manager = false
[[people]]
name = "Paula Reed"
role = "QA — Test Adversary"
personality = "Breaks problems for a living: zero cases, single elements, huge inputs, and cases where the obvious greedy lies. Writes adversarial tests before reading anyone's intended solution. Speaks in reproduction steps. Has caught four flawed problem statements and will catch a fifth."
is_manager = false
[[people]]
name = "Noah Peltz"
role = "Editor"
personality = "Reads every statement aloud (metaphorically) like a magazine editor — unclear prose is a production bug. Writes the writing-style guide and actual example sections with step-by-step walkthroughs. Fixes phrasing of others' problems with polite suggestions in email. Hates inconsistent example numbering."
is_manager = false
# Backlog. effort_days drives progress per work round (100% / effort_days).
[[backlog]]
id = "T1"
title = "Open the dojo: three easy warmup problems"
description = "Setters open our library. Create three DISTINCT easy problems, each as two files: problems/<your-slug>/statement.md (title, statement, input format, output format, 2+ worked examples with constraints) and problems/<your-slug>/tests.json (a JSON array of objects with keys \"in\" and \"out\" — raw stdin text and exact expected stdout, at least 3 tests each incl. an edge case). Pick short kebab-case slugs like maximum-subarray-sum. Do NOT solve them — setters publish, solvers solve."
area = "problems"
effort_days = 2
[[backlog.acceptance]]
file = "problems/**"
min_files = 6
[[backlog]]
id = "T2"
title = "First blood: solve two published easy problems"
description = "Grinders open the round. Check problems/ in the repo for published problems that have NO solution yet under solutions/, write a Python solution as solutions/<slug>/<yourname>.py — a program that reads the case's \"in\" text from stdin and prints exactly the \"out\". Include a 2-line comment with the approach name. Verify against the samples in the statement before submitting."
area = "solutions"
effort_days = 2
[[backlog.acceptance]]
file = "solutions/**"
min_files = 2
[[backlog]]
id = "T3"
title = "Two medium problems, one must force O(n log n)"
description = "Setters go medium. Create two problems with tests (same file contract as the easy set). At least one must be unsolvable by naive brute force within the stated constraints — say so in the statement — so solvers must use sorting, heaps, binary search, or clever data structures."
area = "problems"
effort_days = 3
[[backlog.acceptance]]
file = "problems/**"
min_files = 10
[[backlog]]
id = "T4"
title = "Solve the mediums, note the complexity"
description = "Solvers attack the newest medium problems. Write solutions/<slug>/<yourname>.py per problem. Top of file: a docstring-ish comment stating the algorithm and time complexity, e.g. '# O(n log n) — sort + sweep'. If you can't break it optimally, write the best correct version you can and say what you'd optimize in a comment."
area = "solutions"
effort_days = 3
[[backlog.acceptance]]
file = "solutions/**"
min_files = 4
[[backlog]]
id = "T5"
title = "Test audit: adversarial pass over tests.json"
description = "QA sweeps EVERY problems/*/*tests.json file: each needs 4+ tests including empty/minimal input, a maximum-size input, and a case where the naive greedy fails (add those where missing). Edit the tests.json files in place; append a one-line note in each statement.md's footnote about what was hardened."
area = "qa"
effort_days = 2
[[backlog]]
id = "T6"
title = "The boss problem: one hard DP or graph puzzle"
description = "One showpiece problem — a disguised DP or a graph modeling puzzle. Full statement, constraints where the from-scratch exponential solution is hopeless, and 8+ tests in tests.json. Statement file must include a narrative frame (the dojo voice) plus at least two worked examples."
area = "problems"
effort_days = 3
[[backlog.acceptance]]
file = "problems/**"
min_files = 12
[[backlog]]
id = "T7"
title = "Crack the boss problem + complexity notes"
description = "The elite match: solve the hard problem one. solutions/<slug>/<yourname>.py that passes the published tests, top comment stating the state transition or graph reduction and the total complexity. If you also want to show an intuition doc, write solutions/<slug>/notes.md."
area = "solutions"
effort_days = 3
[[backlog.acceptance]]
file = "solutions/**"
min_files = 6
[[backlog]]
id = "T8"
title = "Rust or JS showpiece: any solution in one non-Python language"
description = "Translation drill: port one solved problem to Rust or JavaScript (solutions/<slug>/<yourname>.rs or .js). The Rust file must compile standalone with `rustc -O`; JavaScript runs under node. Boss manually reviews these since the judge supports .py, .js and precompiled .rs."
area = "solutions"
effort_days = 1
[[backlog]]
id = "T9"
title = "Problems index: problems/README-style catalogue"
description = "Write project index.md at the repo root (name it index.md) listing every published problem: slug, difficulty (easy/medium/hard), algorithmic tag, who wrote it, who solved it, and one-line 'the trick'. Update it as work continues — this is the shop window."
area = "docs"
effort_days = 2
[[backlog.acceptance]]
file = "index.md"
min_lines = 5
[[backlog]]
id = "T10"
title = "Statement polish: ship-ready examples"
description = "Editor's pass on every statement.md: fix inconsistent example numbering, ensure 'Input/Output' blocks are unambiguous prose, walk through sample 1 step by step for at least one problem, and flag any statement that could be read two ways (email the setter instead of silently rewriting, that's the house rule)."
area = "docs"
effort_days = 2