filefunc

One file, one concept. The filename is the concept name.
An AI agent reads check_nesting_depth.go and gets exactly one function. No scrolling past 19 irrelevant helpers in utils.go.
A code structure convention and CLI toolchain for LLM-native development in Go, Python, TypeScript, C#, Java, and Rust — backend services, CLI tools, code generators, and SSOT validators. Not intended for algorithm libraries or low-level systems programming.
Case Studies
typer — Python CLI framework (1155 tests, 0 failures)
Refactored fork of fastapi/typer, restructured to pass filefunc validate --lang python with zero violations.
| Metric |
Original |
Refactored |
| Source files |
16 |
197 |
| filefunc violations |
69 |
0 |
| pytest passed |
1155 |
1155 |
| pytest failed |
0 |
0 |
All public APIs, import paths, and runtime behavior are identical to the original. No performance regression (import +2% within noise, all other benchmarks identical). Verified by full pytest suite and exhaustive comparison.
hono — TypeScript web framework (4419 tests, 0 new failures)
Refactored fork of honojs/hono, restructured to pass filefunc validate --lang typescript with zero violations.
| Metric |
Original |
Refactored |
| Source files |
186 |
626 |
| filefunc violations |
397 |
0 |
| vitest passed |
4419 |
4419 |
| vitest failed |
4 |
4 (pre-existing) |
All import paths and runtime behavior identical to original. Verified by full vitest suite.
Quick Start
npx skills add park-jun-woo/filefunc
go install github.com/park-jun-woo/filefunc/cmd/filefunc@latest
Or build from source:
git clone https://github.com/park-jun-woo/filefunc.git
cd filefunc
CGO_ENABLED=1 go build ./cmd/filefunc/
Requires Go 1.20+ and a C compiler (gcc/clang). C#, Java, and Rust parsing uses tree-sitter via cgo, so CGO_ENABLED=1 and a working C toolchain are required to build. There is no runtime dependency — the grammars are compiled into the binary (no node/python3/dotnet/jdk/cargo needed at runtime).
Using it with AI
The case studies above were measured with AI agents doing the refactoring while filefunc validated them. Claude Code, Codex, Copilot, Cursor — any agent works.
Start the agent, give it one prompt:
Read SKILL.md and refactor this project to pass filefunc validate.
The AI splits files. filefunc validate catches structural violations the moment they appear. The agent stays free within the rails; step off the rails and validation fails fast.
Why
AI code agents (Claude Code, etc.) navigate code via grep → read. The unit of read is a file. If file = concept, then every read returns exactly one relevant thing.
# Without filefunc
read utils.go → 20 funcs, 19 irrelevant. Context pollution.
# With filefunc
read check_one_file_one_func.go → 1 func. Exactly what you needed.
It's more important to NOT open 290 irrelevant functions than to pick the right 5-10.
The primary citizen of filefunc is the AI agent, not the human. File count explosion is a feature, not a bug — more files means smaller files, less noise per read. Human convenience is solved at the view layer (VSCode extensions, etc.).
Commands
validate — Check code structure rules
filefunc validate # current directory as project root
filefunc validate /path/to/project # explicit project root
filefunc validate --format json
filefunc validate --lang python # language override
[PASS] 127 files checked, 0 violations
Project root must contain go.mod (Go), pyproject.toml (Python), package.json (TypeScript), .csproj/.sln (C#), pom.xml/build.gradle (Java), or Cargo.toml (Rust), plus codebook.yaml. Read-only. Exit code 1 on violations. Respects .ffignore. Language is auto-detected; override with --lang go|python|typescript|csharp|java|rust. Powered by toulmin argumentation engine — rules are generic functions with backing-based judgment criteria, exceptions are defeats in a graph.
chain — Trace call relationships
filefunc chain func RunAll --chon 2 --meta what
── Func Chain: RunAll (chon=2) ──
[self] RunAll //ff:what 전체 검증 실행
[child] RunProjectRules //ff:what P 룰 실행
[child] RunCodebookRules //ff:what C 룰 실행
[child] RunFileRules //ff:what F/Q/A 룰 실행
[co] FormatResult //ff:what 검증 결과 포매팅
[co] PrintReport //ff:what 검증 결과 출력
filefunc chain func RunAll # 1촌 (default, current dir)
filefunc chain func RunAll --chon 2 # 2촌 (co-called included)
filefunc chain func RunAll --chon 3 # 3촌 (max)
filefunc chain func RunAll --child-depth 3 # calls only
filefunc chain func RunAll --parent-depth 3 # callers only
filefunc chain feature validate # all funcs in feature
filefunc chain func RunAll --chon 2 --meta what \
--prompt "nesting depth 수정" --rate 0.8 # reranker filtering
filefunc chain func ParseFile --package funcspec # limit to specific package
Real-time AST analysis. Respects .ffignore.
| Flag |
Description |
Default |
--root |
Project root |
. |
--chon |
Relationship distance (1~3) |
1 |
--child-depth |
Trace calls only to this depth |
— |
--parent-depth |
Trace callers only to this depth |
— |
--meta |
Include annotation metadata (meta,what,why,checked,all) |
— |
--package |
Limit to funcs in this Go package (chain func only) |
— |
--prompt |
User task intent for relevance scoring (requires vLLM) |
— |
--rate |
Relevance score threshold (0.0~1.0) |
0.8 |
--model |
Reranker model name |
Qwen/Qwen3-Reranker-0.6B |
--score-endpoint |
vLLM endpoint for reranker |
http://localhost:8000 |
--prompt requires a vLLM server running Qwen3-Reranker-0.6B:
pip install vllm
vllm serve Qwen/Qwen3-Reranker-0.6B --task score \
--hf_overrides '{"architectures":["Qwen3ForSequenceClassification"],"classifier_from_token":["no","yes"],"is_original_qwen3_reranker":true}'
context — LLM context search
filefunc context "nesting depth 검증 수정" # 4-stage pipeline
filefunc context "modify depth logic" --depth 2 # feature filter only
filefunc context "depth 수정" --what-rate 0.3 # adjust what threshold
filefunc context "depth 수정" --body-rate 0.5 # adjust body threshold
filefunc context "depth 수정" --search "feature=validate" # skip LLM, direct filter
filefunc context "cross 수정" --search "feature=crosscheck ssot=openapi" # multi-key AND
4-stage pipeline: LLM feature selection → feature filter → what scoring (LLM) → body scoring (LLM). No func name needed. Requires ollama with gpt-oss:20b.
| Flag |
Description |
Default |
--depth |
Pipeline depth (1-4) |
4 |
--what-rate |
What scoring threshold |
0.2 |
--body-rate |
Body scoring threshold |
0.5 |
--model |
ollama model |
gpt-oss:20b |
--endpoint |
ollama endpoint |
http://localhost:11434 |
--search |
Direct annotation filter (skip LLM feature selection) |
— |
llmc — LLM verification
filefunc llmc # current directory
filefunc llmc /path/to/project # explicit project root
filefunc llmc --model qwen3:8b
filefunc llmc --threshold 0.9
Verifies //ff:what matches func body using local LLM (ollama). Scores 0.0~1.0, threshold 0.8. On pass, writes //ff:checked signature. Respects .ffignore.
| Flag |
Description |
Default |
--provider |
LLM provider |
ollama |
--model |
Model name |
gpt-oss:20b |
--endpoint |
API endpoint |
http://localhost:11434 |
--threshold |
Minimum passing score |
0.8 |
Rules
All rules defined in rulebook.md (SSOT). Categories: P (project), I (import), F (file structure), Q (code quality), A (annotation), C (codebook), N (naming).
Validation order:
1. P rules (project level) — single language check
2. C rules (codebook) — codebook.yaml integrity
3. I rules (import) — circular import detection (Python, TypeScript)
4. F/Q/A rules (file level) — via toulmin defeats graph
P or C violations block subsequent validation.
Annotations
//ff:func feature=validate type=rule control=sequence
//ff:what F1: validates one func per file
//ff:why Primary citizen is AI agent. 1 file 1 concept prevents context pollution.
//ff:checked llm=gpt-oss:20b hash=a3f8c1d2 (auto-generated by llmc)
func CheckOneFileOneFunc(gf *model.GoFile) []model.Violation {
control= is required for all func files (A9). Values: sequence, selection (switch), iteration (loop). Based on Bohm-Jacopini theorem (1966). 1 func 1 control.
dimension= is required for control=iteration files (A15). Specifies the dimensionality of the data being iterated. Q1 depth limit = dimension + 1. dimension=1 for flat lists (depth <= 2), dimension >= 2 requires named type (struct/interface) nesting.
| Annotation |
Purpose |
Required |
//ff:func |
Func metadata (feature, type, etc.) |
Yes (func files) |
//ff:type |
Type metadata (feature, type, etc.) |
Yes (type files) |
//ff:what |
One-line description — what it does |
Yes |
//ff:why |
Design decision — why it's this way |
No |
//ff:checked |
LLM verification signature |
Auto (filefunc llmc) |
Python uses # ff:func, # ff:what, etc. TypeScript, C#, Java, and Rust use // ff:func, // ff:what, etc.
Codebook
The codebook defines allowed values for annotations. It's the project's vocabulary — the map that makes grep precise.
# codebook.yaml
required:
feature:
validate: "Code structure rule validation"
parse: "Source code, annotation, codebook parsing"
type:
command: "cobra command entrypoint"
rule: "Individual validation rule"
optional:
pattern:
error-collection: "Collect errors, report in batch"
level:
error: ""
warning: ""
Each value has a description (key: "description"). Descriptions are used by filefunc context for LLM feature selection. required keys must be present in every annotation (A8). optional keys are used when relevant.
Values not in the codebook trigger A2 ERROR. Each project has its own codebook. codebook.yaml is required.
Codebook format rules (C1-C4) in rulebook.md. Codebook is validated first. If codebook fails, code validation does not run.
.ffignore
Exclude paths from all filefunc commands. Place .ffignore in the project root (next to go.mod). Same syntax as .gitignore. Supports path-based patterns.
# Example .ffignore
vendor/
*.pb.go
*_gen.go
internal/legacy/
Optional. If absent, nothing is excluded.
Academic Basis
- "Lost in the Middle" (Stanford, 2024) — Relevant info in the middle of context drops performance 30%+.
- "Context Length Alone Hurts LLM Performance" (Amazon, 2025) — Even blank tokens degrade performance (13.9~85%). Short focused context wins.
- "Context Rot" (Chroma Research) — Focused prompt > full prompt across all models.
Research proved "shorter context is better." filefunc is the missing tool that structurally splits code so only the relevant parts enter context.
License
MIT — see LICENSE.