moncefem Claude Opus 4.8 commited on
Commit
481fbb6
·
0 Parent(s):

Memory-LoRA hypernetwork for Gemma-4-E2B: code, curated data, sixview checkpoints

Browse files

Hypernetwork that generates repo-specific LoRA adapters for a frozen
google/gemma-4-E2B (zero inference-time token overhead). Includes the
memory_lora package, all data/build/train/eval scripts, the aligned
6-view dataset, and the sixview_v1/v2 checkpoints.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CeUvTz4vLw4ni2ZNR6pS1p

Files changed (44) hide show
  1. .gitattributes +2 -0
  2. .gitignore +51 -0
  3. README.md +581 -0
  4. data/docs/documents.jsonl +0 -0
  5. data/docs/multiview_sources.jsonl +0 -0
  6. data/docs/multiview_sources_balanced.jsonl +0 -0
  7. data/docs/techlead_sources.jsonl +0 -0
  8. data/docs/techlead_sources_commitpack.jsonl +0 -0
  9. data/embeddings/aligned6_embeddings.parquet +3 -0
  10. data/embeddings/multiview_embeddings.parquet +3 -0
  11. data/multilang_repo_list.txt +3150 -0
  12. data/qna/aligned6_qna.jsonl +0 -0
  13. data/qna/repo_scoped_qa.jsonl +0 -0
  14. data/repo_list.txt +800 -0
  15. memory_lora/codegraph.py +221 -0
  16. memory_lora/core.py +434 -0
  17. memory_lora/data_paths.py +32 -0
  18. memory_lora/encoder.py +268 -0
  19. requirements.txt +22 -0
  20. runs/sixview_v1/head.best.pt +3 -0
  21. runs/sixview_v1/head.latest.pt +3 -0
  22. runs/sixview_v1/metrics.jsonl +11 -0
  23. runs/sixview_v1/tb/events.out.tfevents.1784911625.MAC-722851.16547.0 +0 -0
  24. runs/sixview_v2/head.snapshot.pt +3 -0
  25. runs/sixview_v2/head.t0030m.pt +3 -0
  26. runs/sixview_v2/tb/events.out.tfevents.1784929857.MAC-722851.35539.0 +0 -0
  27. scripts/assemble_6view_dataset.py +88 -0
  28. scripts/augment_paraphrases.py +120 -0
  29. scripts/build_doc_embeddings.py +78 -0
  30. scripts/build_repo_multiview.py +245 -0
  31. scripts/consolidate_qa.py +59 -0
  32. scripts/convert_real_code2lora.py +209 -0
  33. scripts/diag_mps_leak.py +101 -0
  34. scripts/eval_memory_lora.py +231 -0
  35. scripts/generate_commitpack_qa.py +153 -0
  36. scripts/generate_repo_scoped_qa.py +133 -0
  37. scripts/generate_synthetic_dataset.py +545 -0
  38. scripts/generate_techlead_qa.py +146 -0
  39. scripts/merge_corpora.py +85 -0
  40. scripts/show_eval_examples.py +71 -0
  41. scripts/test_embed_this_repo.py +43 -0
  42. scripts/test_recall_this_repo.py +99 -0
  43. scripts/train_direct_lora.py +277 -0
  44. scripts/train_memory_lora.py +668 -0
.gitattributes ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ *.pt filter=lfs diff=lfs merge=lfs -text
2
+ *.parquet filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # === Secrets & environment (NEVER commit) =================================
2
+ .env
3
+ .env.*
4
+ *.key
5
+ *.pem
6
+
7
+ # === Python virtualenv & caches ===========================================
8
+ venv/
9
+ .venv/
10
+ env/
11
+ __pycache__/
12
+ *.py[cod]
13
+ *.egg-info/
14
+ .ipynb_checkpoints/
15
+ .DS_Store
16
+
17
+ # === Large raw / intermediate data we deliberately DON'T publish ===========
18
+ # (kept local; regenerable from scripts. See README §8 Datasets inventory.)
19
+ data/commitpack/
20
+ data/real_code2lora/
21
+ data/openrouter_cache/
22
+ data/embeddings/combined_embeddings.parquet
23
+ data/embeddings/real_code2lora_embeddings.parquet
24
+ data/embeddings/real_code2lora_diffs.parquet
25
+ data/embeddings/doc_embeddings.parquet
26
+ data/qna/combined_qna.jsonl
27
+ data/qna/real_code2lora_qna.jsonl
28
+ data/qna/qna.jsonl
29
+
30
+ # === Superseded / exploratory training runs (see README §9) ================
31
+ # Published checkpoints are the current sixview_* line only.
32
+ runs/full2/
33
+ runs/full_real_v4/
34
+ runs/full1/
35
+ runs/full3_priority/
36
+ runs/smoke_combined/
37
+ runs/direct_paper/
38
+ runs/direct_paper_v2/
39
+ runs/direct_cah_baseline/
40
+ runs/full_real_v1_train.log
41
+ runs/*.log
42
+ runs/*.npy
43
+ runs/test_ckpt.pt
44
+
45
+ # Actively-written live checkpoint (overwritten every 50 steps during training;
46
+ # we publish a verified snapshot + the write-once timestamped checkpoints instead)
47
+ runs/sixview_v2/head.latest.pt
48
+
49
+ # === Scratch ===============================================================
50
+ scratchpad/
51
+ *.tmp
README.md ADDED
@@ -0,0 +1,581 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Memory-LoRA: A Hypernetwork that Writes Repo-Specific Adapters for Gemma-4-E2B
2
+
3
+ > **One line:** we train a small neural network (a *hypernetwork*) that reads an
4
+ > embedding of a codebase and **emits a LoRA adapter** for a frozen
5
+ > `google/gemma-4-E2B`. The adapter injects repo-specific knowledge into the
6
+ > model with **zero extra tokens at inference time** — no RAG, no context stuffing.
7
+ > Everything runs **locally on an Apple-Silicon Mac** (M4 Pro, 64 GB).
8
+
9
+ This document is the onboarding bible for the project. It covers *what* we built,
10
+ *why* every non-obvious choice was made, *what data* we used, *every experiment we
11
+ ran and its result*, and the **hard-won lessons** (the MPS memory leak alone cost
12
+ us hours). Read it top to bottom once; after that use it as a reference.
13
+
14
+ ---
15
+
16
+ ## Table of Contents
17
+
18
+ 1. [The idea in 60 seconds](#1-the-idea-in-60-seconds)
19
+ 2. [Origin: the Code2LoRA paper](#2-origin-the-code2lora-paper)
20
+ 3. [Architecture](#3-architecture)
21
+ 4. [The target model: Gemma-4-E2B specifics](#4-the-target-model-gemma-4-e2b-specifics)
22
+ 5. [Data pipeline: the 6 views](#5-data-pipeline-the-6-views)
23
+ 6. [Data pipeline: QA generation](#6-data-pipeline-qa-generation)
24
+ 7. [What is learnable — Tier A / B / C](#7-what-is-learnable--tier-a--b--c)
25
+ 8. [Datasets inventory](#8-datasets-inventory)
26
+ 9. [Experiments & results](#9-experiments--results)
27
+ 10. [Key decisions & lessons learned](#10-key-decisions--lessons-learned)
28
+ 11. [Repository map](#11-repository-map)
29
+ 12. [How to run it](#12-how-to-run-it)
30
+ 13. [Evaluation methodology](#13-evaluation-methodology)
31
+ 14. [Costs & budget discipline](#14-costs--budget-discipline)
32
+ 15. [Current status & roadmap](#15-current-status--roadmap)
33
+ 16. [Glossary](#16-glossary)
34
+
35
+ ---
36
+
37
+ ## 1. The idea in 60 seconds
38
+
39
+ A coding agent (Claude Code, Codex, etc.) is great at reasoning but knows nothing
40
+ about *your* repo until you paste files into its context — which is slow, expensive,
41
+ and capped by the context window. The usual fix is RAG (retrieve chunks at query
42
+ time). We do something different and complementary:
43
+
44
+ **We bake the repo's "personality" directly into the model's weights, once, as a
45
+ LoRA adapter — and we generate that adapter with a neural network instead of
46
+ training it.**
47
+
48
+ ```
49
+ ┌─────────────────────────────┐
50
+ repo on disk ──────► │ 6-view extractor + Qwen3 │ ──► 12288-d
51
+ │ frozen embedding encoder │ repo embedding
52
+ └─────────────────────────────┘ │
53
+
54
+ ┌──────────────────────────┐
55
+ │ HYPERNETWORK (our head) │
56
+ │ MLP → per-module A,B │
57
+ └──────────────────────────┘
58
+ │ LoRA weights
59
+
60
+ Q: "what layer owns auth in this repo?" ──► ┌──────────────────────────────┐
61
+ │ FROZEN Gemma-4-E2B + injected │ ──► "the middleware
62
+ │ LoRA (zero extra tokens) │ layer, via ..."
63
+ └──────────────────────────────┘
64
+ ```
65
+
66
+ The magic: **the hypernetwork is trained across hundreds of repos**, so it learns
67
+ the *mapping* `repo embedding → good adapter`. At inference on a brand-new repo it
68
+ has never seen, it embeds the repo once and produces an adapter in a single forward
69
+ pass. This is the same reason the source paper needed 400+ repos, not 1: breadth is
70
+ what makes the mapping generalize.
71
+
72
+ ---
73
+
74
+ ## 2. Origin: the Code2LoRA paper
75
+
76
+ We reverse-engineered **Code2LoRA** (arXiv 2606.06492v1) and found its released
77
+ code (`anonymous.4open.science/r/code2lora-6857`, MIT). The paper's contribution:
78
+ a *static hypernetwork* that maps a **repository** embedding → a LoRA adapter for a
79
+ frozen code LLM, evaluated on **RepoPeftBench** with IR (in-repo) / CR (cross-repo)
80
+ splits. On a full H100 setup they report **63.8 % cross-repo Exact Match**.
81
+
82
+ Our project is the **Doc2LoRA variant** the paper itself cites — hypernetwork maps a
83
+ *document/repo view* → LoRA — reimplemented against **Gemma-4-E2B**, trained fully
84
+ **locally on MPS** (no CUDA/H100), and extended in two directions the paper does not
85
+ cover:
86
+
87
+ - **Memory / recall**: the adapter should let the model *recall facts* about the
88
+ repo, not just complete code.
89
+ - **Tech-Lead judgment**: architecture, data-flow, conventions, contracts, ops —
90
+ the things a 20-year senior engineer "just knows" about a codebase.
91
+
92
+ We keep the paper's proven autograd trick almost verbatim (see §3) and change only
93
+ what Gemma-4 and Apple Silicon force us to change.
94
+
95
+ ---
96
+
97
+ ## 3. Architecture
98
+
99
+ Three frozen/learned pieces. Only the middle one (the head) is trained.
100
+
101
+ ### 3.1 Frozen encoder — `memory_lora/encoder.py`
102
+
103
+ - **Qwen3-Embedding-0.6B**, frozen, no gradient flows through it.
104
+ - Each repo view is chunked into token windows (2048 tokens, 128 overlap), each
105
+ chunk mean-pooled, then chunks combined with **mean + max pooling** → a **2048-d**
106
+ vector *per view*.
107
+ - Embeddings are **precomputed once and cached** to parquet — the encoder never runs
108
+ during training.
109
+
110
+ ### 3.2 The hypernetwork head — `memory_lora/core.py :: MemoryLoRAHead`
111
+
112
+ The only trained component. Design (kept close to the paper):
113
+
114
+ - **2-layer GELU MLP trunk** (`input_dim → hidden_dim → hidden_dim`), followed by
115
+ **L2-normalize + √hidden_dim rescale** (stabilizes the magnitude of generated
116
+ weights).
117
+ - **Per-module-type output heads**: for each target module *type* it emits an
118
+ `A ∈ [rank, in_features]` and `B ∈ [out_features, rank]`. **One (A,B) pair per
119
+ type, shared across all layers of that type** — this is what keeps the head
120
+ tractable (188.6 M params) instead of exploding per-layer.
121
+ - **Squashing**: `tanh(raw) * exp(log_scale)` with a learned per-type `log_scale`
122
+ (init **-3.5**). This starts the generated adapter near-zero (so training begins
123
+ close to the base model) and lets each type learn its own output scale.
124
+ - **Defaults**: `hidden_dim=128`, `rank=16`, `dropout=0.1`.
125
+ - *Why hidden_dim=128 and not the paper's 512/1024?* A 745 M-param head
126
+ (hidden_dim=512) barely moved eval loss (~1.9 → ~2.7) but was far heavier to
127
+ train on MPS. 128 cuts head size dramatically with negligible quality loss
128
+ locally. Bump it later on real GPUs.
129
+
130
+ ### 3.3 The LoRA injection — `memory_lora/core.py :: LoRA`
131
+
132
+ ```
133
+ base nn.Linear (FROZEN) hypernetwork output
134
+ │ │
135
+ x ──►│ Wx ────────────────┐ │
136
+ │ (input detached +──► y = Wx + scaling · B (A x)
137
+ │ into base) │ ▲ ▲
138
+ x ──────────────────────────┘ │ │
139
+ A,B are NON-detached tensors so
140
+ autograd flows LM-loss → head
141
+ ```
142
+
143
+ Critical detail (straight from the paper's code): **A and B are plain, non-buffer
144
+ tensor attributes, not `nn.Parameter` and not detached**, so the gradient of the LM
145
+ loss flows *through* the injected weights *into the hypernetwork*. The base
146
+ `nn.Linear` is frozen and its input is detached. Get this wrong and the head never
147
+ learns.
148
+
149
+ ### 3.4 Shape-qualified module types — the heterogeneity fix
150
+
151
+ Gemma-4-E2B is **not** a uniform stack (see §4). Two `q_proj`s can have different
152
+ shapes. If you key the head by bare type name (`q_proj`) you get
153
+ *"type q_proj inconsistent dims"* crashes. Fix: key by **shape-qualified type**,
154
+ e.g. `q_proj_1536x2048` vs `q_proj_1536x4096`. The v2 run discovered **14 shape
155
+ types** across **205 target modules**:
156
+
157
+ ```
158
+ down_proj_12288x1536 down_proj_6144x1536 gate_proj_1536x12288 gate_proj_1536x6144
159
+ k_proj_1536x256 k_proj_1536x512 o_proj_2048x1536 o_proj_4096x1536
160
+ q_proj_1536x2048 q_proj_1536x4096 up_proj_1536x12288 up_proj_1536x6144
161
+ v_proj_1536x256 v_proj_1536x512
162
+ ```
163
+
164
+ `get_module_specs(root_prefix="model.language_model.")` restricts wrapping to the
165
+ text decoder — the **vision and audio towers are never touched** (not even
166
+ inspected), so the multimodal forward path stays intact and they cost only idle RAM.
167
+
168
+ ---
169
+
170
+ ## 4. The target model: Gemma-4-E2B specifics
171
+
172
+ Verified by reading the actual safetensors header, not guessed:
173
+
174
+ - **Real model.** Google shipped Gemma 4 in March 2026. Apache-2.0, ungated.
175
+ Class `Gemma4ForConditionalGeneration`, `model_type: "gemma4"`. Loaded via
176
+ `AutoModelForImageTextToText`.
177
+ - **Requires `transformers >= 5.5.0.dev0`** — install from the `main` branch, not a
178
+ pinned PyPI release (this is the single biggest environment risk; smoke-test first).
179
+ - **Decoder is nested**: layers live at `model.language_model.layers.{i}.*`, *not*
180
+ `model.layers.*`. The layer-index regex had to change accordingly.
181
+ - **35 text layers, heterogeneous:**
182
+ - Aggressive KV sharing — **20 of 35 layers lack their own `k_proj`/`v_proj`**
183
+ (`num_kv_shared_layers=20`).
184
+ - **Every 5th layer is wider** (the `*_4096`, `*_12288` shape variants above).
185
+ - **Device `mps`, precision bf16** (fall back to fp16 if unstable). No
186
+ `flash_attention_2` on MPS — use `sdpa`, fall back to `eager`.
187
+
188
+ ---
189
+
190
+ ## 5. Data pipeline: the 6 views
191
+
192
+ `scripts/build_repo_multiview.py` clones a repo and extracts **6 complementary
193
+ views**, embeds each with Qwen3 → 2048-d, and **concatenates to a 12288-d** repo
194
+ vector. The views encode the different "lenses" a senior engineer uses:
195
+
196
+ | View | What it captures | Source signals |
197
+ |-----------------|----------------------------------------------------|----------------|
198
+ | `v_graph` | call / import / dependency structure | AST for Python (`memory_lora/codegraph.py`); `IMPORT_RE`/`DEF_RE` regex fallback for other languages |
199
+ | `v_arch` | architecture & layout | README, folder tree |
200
+ | `v_history` | how the code evolved | `git log`, recent diffs |
201
+ | `v_contracts` | behavioral contracts | test files |
202
+ | `v_conventions` | idioms & style | representative source files |
203
+ | `v_ops` | build / deploy / runtime | CI config, Dockerfile, build files |
204
+
205
+ **Multi-language from the start.** `CODE_EXTS` + regex fallbacks mean the graph view
206
+ works for 9 languages, not just Python (this was a deliberate correction — see §10).
207
+ Repos with < 3 code files are skipped. The build is **resume-safe** (skips repos
208
+ already in `multiview_sources.jsonl`) and **flushes the embeddings parquet every 10
209
+ repos**, so a crash never loses more than 10 repos of work.
210
+
211
+ ---
212
+
213
+ ## 6. Data pipeline: QA generation
214
+
215
+ The repo embedding is the *input*; the *target* is repo-scoped Q&A. Two generators,
216
+ both parallelized (`ThreadPoolExecutor`, `--workers 10`) with a **per-prompt disk
217
+ cache** (idempotent reruns) and a `--model` flag:
218
+
219
+ - **`scripts/generate_repo_scoped_qa.py`** — reads the same 6 views and asks the LLM
220
+ for **8–12 repo-level judgment questions** ("what layer owns X", "what convention
221
+ does this repo use for Y", "how does data flow through Z", "why is it structured
222
+ this way"). Target scope = input scope (repo-level embedding ↔ repo-level QA).
223
+ - **`scripts/generate_commitpack_qa.py`** — **breadth** generator: one commit per
224
+ *distinct* repo across CommitPackFT (25k+ distinct repos), 3–4 commit-scoped
225
+ judgment questions (why / conventions / contracts / impact). For a hypernetwork,
226
+ **distinct-repo count is the currency of generalization**, so we favor 1 commit ×
227
+ many repos over many commits × one repo.
228
+
229
+ **Discipline (both):** answers are **short judgment**, never file-path/line-number
230
+ lists. This is deliberate — see Tier A/B/C next.
231
+
232
+ **Models used (OpenRouter, OpenAI-compatible API):**
233
+
234
+ | Model | Role | Notes | Cost |
235
+ |-------|------|-------|------|
236
+ | `google/gemini-3.6-flash` | high-quality QA | **reasoning is mandatory** → needs generous `max_tokens` (3000–4000) or it returns empty | ~$0.0021 / QA |
237
+ | `google/gemma-4-31b-it` | bulk / cheap QA | non-reasoning, clean JSON | ~$0.001 / repo (~$1 per 1000 repos) |
238
+
239
+ The OpenRouter key lives in a **git-ignored `.env` (mode 600)** and is never pasted
240
+ into a command line.
241
+
242
+ ---
243
+
244
+ ## 7. What is learnable — Tier A / B / C
245
+
246
+ A LoRA adapter has finite capacity. We classify repo knowledge by whether a LoRA can
247
+ hold it — this drives the entire QA design:
248
+
249
+ - **Tier A — Judgment & conventions** (LEARNABLE). "This repo puts business logic in
250
+ services, not views." Compressible, generalizes. → **This is what we train on.**
251
+ - **Tier B — Structural gist** (LEARNABLE). "Auth flows through middleware." The kind
252
+ of thing, not the exact file.
253
+ - **Tier C — Exact recall & multi-hop** (NOT reliably learnable). "Line 412 of
254
+ `foo.py` calls `bar()`." This needs **retrieval (RAG)**, not weights.
255
+
256
+ So Memory-LoRA and RAG are **complementary**: the adapter carries Tier A/B judgment
257
+ for free (zero tokens); RAG handles Tier C exact lookups. The QA prompts forbid exact
258
+ file/line answers precisely so we never ask the LoRA to do a job it structurally
259
+ can't.
260
+
261
+ ---
262
+
263
+ ## 8. Datasets inventory
264
+
265
+ Everything lives under `data/` (git-ignored blobs). Sizes are approximate.
266
+
267
+ | Path | What | Scale |
268
+ |------|------|-------|
269
+ | `data/real_code2lora/` | **RepoPeftBench** from the `code2lora` HF org — 500 Python repos, repo-commit embeddings + diffs | 73,849 repo-commit rows; ~1.2 GB |
270
+ | `data/commitpack/multilang_commits.jsonl` | **CommitPackFT** shards, 9 languages | 25k+ distinct repos |
271
+ | `data/docs/multiview_sources.jsonl` | 6-view `view_text` per repo (input to QA gen) | growing (1000s of repos) |
272
+ | `data/embeddings/multiview_embeddings.parquet` | 12288-d multi-view repo embeddings | 1000+ repos |
273
+ | `data/embeddings/aligned6_embeddings.parquet` | **assembled training inputs** (repos with ≥1 QA) | 1058 repos (current) |
274
+ | `data/qna/repo_scoped_qa.jsonl` | repo-level judgment QA | 11,232 QA |
275
+ | `data/qna/techlead_qa_commitpack.jsonl` | commit-scoped breadth QA | 9,245 QA |
276
+ | `data/qna/techlead_qa.jsonl` | SWE-bench tech-lead QA | 2,786 QA |
277
+ | `data/qna/aligned6_qna.jsonl` | **assembled training targets** | 8,540 QA (current) |
278
+ | `data/openrouter_cache/` | per-prompt response cache | ~19 MB |
279
+
280
+ **Language balancing.** SWE-bench is ~79 % Django. Left alone, the dataset was 46 %
281
+ Django. `scripts/consolidate_qa.py` applies a **per-repo cap** (default 12–15 QA/repo)
282
+ which collapses Django to **~2.0 %** while preserving the 2400+ distinct repos'
283
+ diversity. `assemble_6view_dataset.py` applies the same cap when building the final
284
+ aligned set.
285
+
286
+ ---
287
+
288
+ ## 9. Experiments & results
289
+
290
+ Chronological, with the actual numbers we measured. Two families of runs.
291
+
292
+ ### 9.1 Reproducing the paper (single-view, real RepoPeftBench)
293
+
294
+ | Run | What | Result |
295
+ |-----|------|--------|
296
+ | `full1` (early) | first end-to-end hypernetwork on converted real data | CR **EM 0.056–0.083**, EditSim ~0.27 — pipeline works, undertrained |
297
+ | `sixview`/converted-real (best single-view ckpt) | after more training | **CR EM 0.524, EditSim 0.635** |
298
+ | Paper (reference, H100) | their full run | CR EM **0.638** |
299
+
300
+ **Headline:** on real code, after only ~2.4 % of one epoch of local MPS training, we
301
+ reached **52.4 % cross-repo Exact Match** vs the paper's 63.8 % on a full H100 setup.
302
+ The mechanism demonstrably works — the generated adapter recovers repo-specific
303
+ identifiers the base model does not know.
304
+
305
+ ### 9.2 The 6-view Tech-Lead model (the current line of work)
306
+
307
+ Loss is causal-LM cross-entropy on QA targets; lower is better. Three eval suites:
308
+ `cr_val` / `cr_test` (held-out *repos*) and `ir_test` (held-out *QA* of train repos).
309
+
310
+ | Run | Dataset | Best held-out `cr_test` loss | Notes |
311
+ |-----|---------|------------------------------|-------|
312
+ | `sixview_v1` | 515 repos / 3,988 QA (415 train repos) | **2.848** (step ~1060) | Overfit afterward: train loss fell to 1.75 while `cr_test` drifted to 3.35. Classic small-dataset ceiling. |
313
+ | `sixview_v2` | **1,058 repos / 8,540 QA (858 train repos)** | *in progress* | Resumed from `sixview_v1/head.best.pt`; 2× the data specifically to break v1's ceiling. |
314
+
315
+ `sixview_v1` metrics trajectory (from `runs/sixview_v1/metrics.jsonl`):
316
+
317
+ ```
318
+ step 1245 cr_test 2.962 ir_test 2.535 (end of epoch 2 — near best)
319
+ step 1400 cr_test 3.245 ir_test 2.593 (overfitting begins)
320
+ step 1600 cr_test 3.352 ir_test 2.655 (train loss still falling → ceiling hit)
321
+ ```
322
+
323
+ The v1→v2 story is the core empirical lesson: **the small aligned set was the
324
+ bottleneck, not the architecture** — hence the push to build 1000+ more repos.
325
+
326
+ ---
327
+
328
+ ## 10. Key decisions & lessons learned
329
+
330
+ The expensive knowledge. Read this section twice.
331
+
332
+ ### 10.1 ⚠️ The MPS gradient-checkpointing memory leak (the big one)
333
+
334
+ **Symptom:** training with `gradient_checkpointing_enable()` (`use_reentrant=False`)
335
+ **leaked ~12 GB per step** and OOM'd the whole machine within a few steps.
336
+
337
+ **Diagnosis** (`scripts/diag_mps_leak.py`): forward-only was stable; train + checkpoint
338
+ leaked 39 GB → 18 GB free in 2 steps. Isolated the checkpointing path as the cause.
339
+
340
+ **Fix:** **`--no-gradient-checkpointing`.** We have enough unified memory to hold
341
+ activations without it once the multimodal towers sit idle. This is documented as a
342
+ standing memory (`mps-gradient-checkpointing-leak.md`).
343
+
344
+ ### 10.2 ⚠️ `psutil` RSS is blind to MPS memory
345
+
346
+ Our first memory safety-net used `psutil` RSS / `ps -o rss` — it reported **< 1 GB**
347
+ while `top` showed **55–83 GB** actually in use. MPS (GPU) allocations don't show up
348
+ in process RSS.
349
+
350
+ **Fix:** the safety check uses **`psutil.virtual_memory().available`** (system-wide)
351
+ with a `--min-available-gb` floor (default 5). To *observe* MPS memory, use
352
+ `top -l 1 -pid <PID> -stats mem`, not `ps`.
353
+
354
+ ### 10.3 Memory competition between concurrent jobs
355
+
356
+ Three concurrent jobs once pushed available memory under the 10 GB floor and training
357
+ self-stopped. **Lesson:** during MPS training, run data builds/embedding on **CPU**
358
+ (`--device cpu`) so they don't contend for the GPU/unified memory. We now routinely
359
+ run training (MPS) + QA gen (network) + multiview build (CPU) together without
360
+ contention.
361
+
362
+ ### 10.4 Don't lose hours of training
363
+
364
+ Every long run writes **checkpoints every 50 steps** (overwriting `head.latest.pt`),
365
+ **every 30 minutes** (timestamped `head.tNNNNm.pt`), **per-epoch** (`head.epN.pt`),
366
+ and a **`head.best.pt`** on eval improvement. Runs are launched with `nohup … &
367
+ disown` so they survive terminal/session death. `sixview_v1` in fact survived a full
368
+ session interruption and kept training. Resume with `--resume-from <ckpt>` (loads head
369
+ weights; optimizer restarts fresh).
370
+
371
+ ### 10.5 Data-quality corrections (user-driven)
372
+
373
+ - **"I still see lots of Django."** SWE-bench is Django-dominated. → per-repo cap +
374
+ multi-language sourcing dropped Django 46 % → 2.0 %.
375
+ - **"It must be good for any programming language."** → 9-language diversity via
376
+ CommitPackFT and language-agnostic view extraction.
377
+ - **"Where's the code context in the QA?"** → clarified the two-channel design: the
378
+ **repo embedding is the context channel**, the QA is only the target. They are
379
+ joined by `doc_id` at assembly time.
380
+
381
+ ### 10.6 OpenRouter gotchas
382
+
383
+ - `gemini-3.6-flash` **returned empty** until we raised `max_tokens` — it's a
384
+ mandatory-reasoning model that spends tokens on hidden reasoning before content.
385
+ Reasoning **cannot be disabled** (400 error).
386
+ - CommitPackFT's HF loader is deprecated → fetch raw `data.jsonl` directly.
387
+ - `global MODEL` after use is a `SyntaxError` → set via `globals()["MODEL"] = ...`.
388
+
389
+ ### 10.7 Performance fix worth knowing
390
+
391
+ Loading embeddings was 5+ min because `_list_to_f32_array` used a Python loop.
392
+ Vectorized via `col.combine_chunks().flatten().to_numpy()` → **~220× faster**.
393
+
394
+ ---
395
+
396
+ ## 11. Repository map
397
+
398
+ ```
399
+ memory_lora/ # the library (importable package)
400
+ core.py # LoRA wrapper, MemoryLoRAHead hypernetwork,
401
+ # get_module_specs / replace_with_lora / inject_lora_weights,
402
+ # load_doc_rows / load_qna_rows
403
+ encoder.py # Qwen3 chunk + embed + mean/max pool (frozen)
404
+ codegraph.py # Python AST extractor (imports, sigs, call graph)
405
+ data_paths.py # local parquet/jsonl path resolver
406
+
407
+ scripts/
408
+ build_repo_multiview.py # clone → 6 views → 12288-d embeddings (multi-language, resume-safe)
409
+ generate_repo_scoped_qa.py # repo-level judgment QA (aligned to the 6 views)
410
+ generate_commitpack_qa.py # commit-scoped breadth QA across 1000s of distinct repos
411
+ generate_techlead_qa.py # SWE-bench tech-lead QA
412
+ generate_synthetic_dataset.py # original synthetic doc + QA generator
413
+ consolidate_qa.py # per-repo cap → language/domain balancing
414
+ assemble_6view_dataset.py # join embeddings ↔ all QA by repo → aligned6_{embeddings,qna}
415
+ augment_paraphrases.py # QA paraphrase augmentation
416
+ convert_real_code2lora.py # RepoPeftBench → our schema
417
+ build_doc_embeddings.py # encoder pass over documents
418
+ merge_corpora.py # combine multiple corpora
419
+ train_memory_lora.py # THE trainer (MPS, one-repo-per-step, checkpoints, TensorBoard)
420
+ train_direct_lora.py # baseline: plain per-repo LoRA (no hypernetwork)
421
+ eval_memory_lora.py # EM / EditSim recall eval on cr/ir splits
422
+ show_eval_examples.py # dump concrete base-vs-adapted examples
423
+ test_embed_this_repo.py # embed the current repo (pipeline demo)
424
+ test_recall_this_repo.py # query the adapted model about this repo
425
+ diag_mps_leak.py # the memory-leak isolation harness
426
+
427
+ data/ # git-ignored: embeddings, qna, sources, caches
428
+ runs/ # git-ignored: checkpoints, logs, metrics.jsonl, tb/
429
+ requirements.txt # torch 2.13 (MPS), transformers@main, openai, pyarrow, tensorboard…
430
+ .env # git-ignored, mode 600: OPENROUTER_API_KEY
431
+ ```
432
+
433
+ ---
434
+
435
+ ## 12. How to run it
436
+
437
+ ### Setup
438
+
439
+ ```bash
440
+ python3 -m venv venv && source venv/bin/activate
441
+ pip install -r requirements.txt # installs transformers from git main
442
+ echo "OPENROUTER_API_KEY=sk-or-..." > .env && chmod 600 .env
443
+ ```
444
+
445
+ Smoke-test the environment first (gates everything): confirm `transformers` main
446
+ loads `google/gemma-4-E2B` on `mps` and runs a text-only forward pass.
447
+
448
+ ### Build data
449
+
450
+ ```bash
451
+ # 1) multi-view embeddings for a repo list (CPU to stay off the GPU during training)
452
+ python scripts/build_repo_multiview.py \
453
+ --repos-file data/multilang_repo_list.txt --max-repos 1000 --device cpu
454
+
455
+ # 2) repo-scoped QA (cheap model) — appends, resume-safe, cached
456
+ ./venv/bin/python scripts/generate_repo_scoped_qa.py \
457
+ --model google/gemma-4-31b-it --workers 10
458
+
459
+ # 3) balance + assemble the aligned training set
460
+ python scripts/consolidate_qa.py --per-repo-cap 12
461
+ python scripts/assemble_6view_dataset.py
462
+ # -> data/embeddings/aligned6_embeddings.parquet + data/qna/aligned6_qna.jsonl
463
+ ```
464
+
465
+ ### Train (the exact `sixview_v2` command)
466
+
467
+ ```bash
468
+ nohup ./venv/bin/python scripts/train_memory_lora.py --output-dir sixview_v2 \
469
+ --resume-from runs/sixview_v1/head.best.pt \
470
+ --embeddings-path data/embeddings/aligned6_embeddings.parquet \
471
+ --qna-path data/qna/aligned6_qna.jsonl --epochs 100 --max-hours 8 \
472
+ --checkpoint-every-steps 50 --checkpoint-every-minutes 30 --epoch-ckpt-every 5 \
473
+ --eval-every-steps 300 --limit-eval-docs 40 --max-seq-len 512 --fixed-seq-len \
474
+ --max-qna-per-doc 12 --lm-micro-batch 2 --device mps --no-gradient-checkpointing \
475
+ --rank 16 --head-hidden-dim 128 --head-dropout 0.1 --weight-decay 0.05 \
476
+ --early-stop-patience 25 --lr 8e-5 --lr-total-steps 9000 --min-available-gb 5 \
477
+ > runs/sixview_v2_train.log 2>&1 &
478
+ disown
479
+ ```
480
+
481
+ **Flags you must not forget:** `--no-gradient-checkpointing` (the leak),
482
+ `--device cpu` for builds during training (contention), `--min-available-gb`
483
+ (system-wide memory floor).
484
+
485
+ ### Watch it
486
+
487
+ ```bash
488
+ tensorboard --logdir runs/sixview_v2/tb # train/loss, train/lr, eval/{suite}_loss
489
+ tail -f runs/sixview_v2_train.log
490
+ ```
491
+
492
+ ### Evaluate & inspect
493
+
494
+ ```bash
495
+ python scripts/eval_memory_lora.py --ckpt runs/sixview_v2/head.best.pt # EM / EditSim
496
+ python scripts/show_eval_examples.py # base vs adapted
497
+ ```
498
+
499
+ ---
500
+
501
+ ## 13. Evaluation methodology
502
+
503
+ - **Splits (deterministic, by `md5(repo) % 100`):** 80 % train / 10 % `cr_val` /
504
+ 10 % `cr_test` **by repo**, so cross-repo suites are **entirely held-out
505
+ repositories** the hypernetwork never trained on. Within train repos, ~15 % of QA
506
+ is held out → `ir_test` (in-repo generalization to unseen questions of seen repos).
507
+ - **Metrics:** causal-LM **eval loss** during training (fast, every N steps on
508
+ `--limit-eval-docs` docs to stay cheap on CPU), plus generation-time **Exact Match
509
+ (EM)** and **EditSim** for the recall eval.
510
+ - **The proof spot-check:** query the *adapted* model with repo-specific questions and
511
+ confirm the *base* (un-adapted) model gets them wrong/vague — proving the
512
+ **adapter**, not the base model's pretraining, does the work.
513
+
514
+ CPU eval of a float32 5B model is slow (~20 min for a full pass) → we cap eval docs
515
+ (e.g. 10–40) for in-loop evals and run full EM eval separately.
516
+
517
+ ---
518
+
519
+ ## 14. Costs & budget discipline
520
+
521
+ - **Spend baseline:** $31.00 (`runs/spend_baseline.txt`); ~**$33.90 total** to date;
522
+ ~**$11 remaining**. The project is run under explicit budget caps ("spend at most
523
+ $4 more") with spend-guards.
524
+ - **Unit economics:** `gemini-3.6-flash` ≈ **$0.0021/QA**; `gemma-4-31b-it` ≈
525
+ **$0.001/repo (~$1 per 1000 repos)** — which is exactly why the 1000-repo expansion
526
+ uses the gemma model.
527
+ - **Free levers:** the per-prompt cache makes reruns free; embedding and training are
528
+ local (electricity only).
529
+
530
+ ---
531
+
532
+ ## 15. Current status & roadmap
533
+
534
+ **Live right now (three jobs in parallel, no contention):**
535
+
536
+ - **`sixview_v2` training** — resumed from `head.best.pt` on the doubled
537
+ **1,058-repo / 8,540-QA** dataset (858 steps/epoch), MPS. First held-out eval at
538
+ step 300 tells us whether doubling the data broke v1's 2.848 ceiling.
539
+ - **QA generation** — `gemma-4-31b-it` filling in all ~1,032 new repos for the
540
+ **complete** dataset (next training run).
541
+ - **Multiview build** — cloning/embedding toward the full +1,000-new target (CPU).
542
+
543
+ **Roadmap:**
544
+
545
+ 1. Finish the complete 1000-new-repo dataset (embeddings + QA).
546
+ 2. Assemble the full aligned set (~1,650 repos) and train **`sixview_v3`** on it.
547
+ 3. Run generation-time **EM/EditSim** on the 6-view model (base vs adapted).
548
+ 4. Push `head_hidden_dim` back up once on real GPUs; the 128 default was an
549
+ MPS-locality compromise.
550
+ 5. Broaden Tier-A/B QA toward agent-harness use cases (Jira/ticket tracking,
551
+ diff/impact reasoning) already scaffolded in `generate_techlead_qa.py`.
552
+
553
+ **Open questions:**
554
+
555
+ - Does the 12288-d 6-view embedding actually beat the single 2048-d view on
556
+ generation EM, or only on loss? (loss says yes; EM eval pending)
557
+ - What's the real Tier-B ceiling — how much structural gist fits in rank-16?
558
+ - Optimal per-repo QA cap for the breadth/depth trade-off.
559
+
560
+ ---
561
+
562
+ ## 16. Glossary
563
+
564
+ - **Hypernetwork** — a network that outputs the weights of another network. Here:
565
+ repo embedding → LoRA (A,B) matrices.
566
+ - **LoRA** — Low-Rank Adaptation: `y = Wx + scaling · B(Ax)`, with `A,B` low-rank
567
+ (rank 16). We *generate* A,B instead of training them per-repo.
568
+ - **6 views** — graph / arch / history / contracts / conventions / ops; each 2048-d,
569
+ concatenated to 12288-d.
570
+ - **CR / IR** — cross-repo (held-out repos) / in-repo (held-out QA of seen repos).
571
+ - **EM / EditSim** — Exact Match / edit-distance similarity of generated vs gold.
572
+ - **Tier A/B/C** — judgment (learnable) / structural gist (learnable) / exact recall
573
+ (needs RAG).
574
+ - **MPS** — Apple's Metal Performance Shaders GPU backend for PyTorch.
575
+ - **RepoPeftBench** — the paper's benchmark; 500 Python repos, repo-commit
576
+ embeddings + diffs, IR/CR splits.
577
+
578
+ ---
579
+
580
+ *Maintained as living documentation. If you change a default, a path, or a flag,
581
+ update the matching section here — onboarding depends on it.*
data/docs/documents.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
data/docs/multiview_sources.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
data/docs/multiview_sources_balanced.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
data/docs/techlead_sources.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
data/docs/techlead_sources_commitpack.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
data/embeddings/aligned6_embeddings.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4c86fc8e4a4abe8e47415e0ecd876627623fb02f9c9aabd3740a878319609e14
3
+ size 68653613
data/embeddings/multiview_embeddings.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:deb4c9f45b62fb7b552f27795054cfaf4ab5a511e94350eab1651e4941fbb3a9
3
+ size 88090938
data/multilang_repo_list.txt ADDED
@@ -0,0 +1,3150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ RangeeGmbH/FreeRDP c
2
+ SpectoLabs/hoverfly go
3
+ saidie/plantuml-api java
4
+ teampopong/pokr.kr javascript
5
+ trevormunoz/katherine-anne php
6
+ imankulov/sentry python
7
+ waxpoetic/brotherly ruby
8
+ alerque/casile rust
9
+ geofffilippi/angular-cli typescript
10
+ pivotaltracker/PivotalCoreKit c
11
+ kubernetes-retired/cluster-registry go
12
+ palmfjord/twig-java java
13
+ TimBek2/phase-0 javascript
14
+ i-lateral/silverstripe-catalogue php
15
+ rnyberg/pyfibot python
16
+ neotericdesign/pubdraft ruby
17
+ osa1/tiny rust
18
+ sebastienbarbier/sebastienbarbier.com typescript
19
+ melonmanchan/k-and-r c
20
+ jehrhardt/bowling-game-go go
21
+ CS2103AUG2016-T15-C1/main java
22
+ motion/motion javascript
23
+ etu/0bRSS php
24
+ artefactual/archivematica-history python
25
+ mirego/rack-locale-root-redirect ruby
26
+ CryZe/livesplit-core rust
27
+ crossroads-education/eta-front typescript
28
+ vespa-engine/vespa c
29
+ bitly/go-hostpool go
30
+ edx/edx-app-android java
31
+ tesfaldet/bluebird javascript
32
+ Ecodev/gims php
33
+ caleb531/automata python
34
+ jtribe/redirector ruby
35
+ jgilchrist/rslike rust
36
+ auth0-blog/ng2-dinos typescript
37
+ Baltoli/peggo c
38
+ polydawn/refmt go
39
+ cbornet/generator-jhipster java
40
+ hanford/filepizza javascript
41
+ spatie/laravel-permission php
42
+ Antiun/account-invoicing python
43
+ tenforwardconsulting/crantastic ruby
44
+ xfix/enum-map rust
45
+ itchio/itch typescript
46
+ peteruhnak/pharo-vm c
47
+ prometheus/client_golang go
48
+ Yakindu/statecharts java
49
+ mbland/hubot-slack-github-issues javascript
50
+ anawatom/lavandula php
51
+ ElementalAlchemist/txircd python
52
+ arkon/Markus ruby
53
+ zanesterling/fatr rust
54
+ rcjsuen/dockerfile-language-server-nodejs typescript
55
+ carp-lang/Carp c
56
+ jabley/cf-metrics go
57
+ s-case/s-case-core java
58
+ grncdr/node-any-db javascript
59
+ routetopa/auth-server-2 php
60
+ kmee/stock-logistics-warehouse python
61
+ sophsec/wordlist ruby
62
+ sunjay/turtle rust
63
+ jonbern/fetch-retry typescript
64
+ Ultimaker/CuraEngine c
65
+ lucapette/deloominator go
66
+ smartnews/presto java
67
+ jonathanargentiero/istanbul-instrumenter-loader javascript
68
+ aedart/scaffold php
69
+ BT-rmartin/partner-contact python
70
+ davengeo/github ruby
71
+ matthiasbeyer/task-hookrs rust
72
+ rafaell-lycan/sabesp-mananciais-api typescript
73
+ iondbproject/iondb c
74
+ cburkert/go-statusbar go
75
+ realityforge/replicant java
76
+ itsananderson/cascadiafest javascript
77
+ herloct/pinger php
78
+ yuzie007/upho python
79
+ agrimm/resume ruby
80
+ zsiciarz/24daysofrust rust
81
+ JiraGoggles/jiragoggles-frontend typescript
82
+ llvm-mirror/clang c
83
+ ryanclarke/hugo go
84
+ bwyap/java-familyfeud java
85
+ ProseMirror/prosemirror-markdown javascript
86
+ Payum/Payum php
87
+ bfaludi/daprot python
88
+ joyent/lx-brand-image-tests ruby
89
+ dcoles/experiments rust
90
+ dainst/idai-components-2 typescript
91
+ basho-labs/riak-c-client c
92
+ goaltools/goal go
93
+ flanglet/kanzi java
94
+ asennikov/ember-g-map javascript
95
+ orchestral/config php
96
+ angr/cle python
97
+ yutarody/homebrew-cask ruby
98
+ bash/radium rust
99
+ sly7-7/ember.js typescript
100
+ geoffgarside/cocoagit c
101
+ nylar/wally go
102
+ rigregs/ez-rules java
103
+ GitbookIO/plugin-katex javascript
104
+ Kunstmaan/KunstmaanArticleBundle php
105
+ jmenglund/CollectionBatchTool python
106
+ dphaener/kanji ruby
107
+ onefrankguy/chifir rust
108
+ PRX/publish.prx.org typescript
109
+ wmadill/grant-lighting c
110
+ jessecarl/goDLX go
111
+ marques-work/gocd java
112
+ fleetlog/gmaps-signer javascript
113
+ stakx-io/stakx php
114
+ coleifer/scout python
115
+ SumOfUs/Champaign ruby
116
+ badboy/rustup-version-name rust
117
+ AzureAD/microsoft-authentication-library-for-js typescript
118
+ MattDevo/edk2 c
119
+ nicolasmccurdy/run go
120
+ cucumber/cucumber-jvm java
121
+ cletusw/eslint-plugin-local-rules javascript
122
+ Respect/Foundation php
123
+ hsercanatli/adaptivetuning python
124
+ AustenLamacraft/austenlamacraft.github.io ruby
125
+ google/serde_json_lenient rust
126
+ BibleBot/BibleBot typescript
127
+ elsys/po-homework c
128
+ perrito666/juju go
129
+ GlowstonePlusPlus/GlowstonePlusPlus java
130
+ jstransformers/jstransformer-reshape javascript
131
+ wandersonwhcr/romans php
132
+ krmaxwell/TRX python
133
+ vonconrad/cabinet ruby
134
+ jmacdonald/scribe rust
135
+ gamejolt/frontend-lib typescript
136
+ mesham/ndm c
137
+ VonC/gopanic go
138
+ b0noI/TicTacToe java
139
+ thoughtpalette/gulp-replace javascript
140
+ darimpulso/koala-framework php
141
+ svieira/Flask-HipPocket python
142
+ blinkboxbooks/common_config.rb ruby
143
+ diesel-rs/diesel rust
144
+ cardstack/cardstack typescript
145
+ spotify/JniHelpers c
146
+ jolshevski/chester go
147
+ sebastiansokolowski/ReservationSystem-BJ java
148
+ then/then-request javascript
149
+ M6Web/AmqpBundle php
150
+ capybaralet/fuel python
151
+ osaris/sp-gestion ruby
152
+ frewsxcv/tiny-http rust
153
+ Shopify/tinymce typescript
154
+ lis-epfl/MAVRIC_Library c
155
+ voxelbrain/pixelpixel go
156
+ SleeplessAcorn/DimensionallyTranscendentalTents java
157
+ mmalecki/package-json-dependencies-to-array javascript
158
+ KilikFr/TableBundle php
159
+ openstack/akanda-rug python
160
+ PRX/cms.prx.org ruby
161
+ fede1024/rust-rdkafka rust
162
+ orbitjs/orbit.js typescript
163
+ felipejfc/xserver-xorg-input-synaptics c
164
+ moncho/dry go
165
+ torodb/server java
166
+ patientslikeme/react-select-test-utils javascript
167
+ nicksagona/PopPHP php
168
+ glyph/txsni python
169
+ tsub/dotfiles ruby
170
+ lise-henry/crowbook-text-processing rust
171
+ glimmerjs/glimmer-vm typescript
172
+ fabriciofmsilva/labs c
173
+ art4711/bsearch go
174
+ tectronics/stickycode java
175
+ seattletimes/newsapp-template javascript
176
+ Becklyn/SearchBundle php
177
+ tiddlyweb/tiddlywebplugins.atom python
178
+ deep-cover/deep-cover ruby
179
+ Vectorious/geom-rs rust
180
+ agdsn/pycroft typescript
181
+ DBOTW/pick c
182
+ WarCluster/warcluster-server go
183
+ DadanielZ/incubator-eagle java
184
+ civicsource/knockout-place-picker javascript
185
+ khounnouk/ScnSocialAuth php
186
+ grimwm/py-dictobj python
187
+ rackspace-cookbooks/varnish ruby
188
+ Sgeo/hlist-old rust
189
+ pkarw/vue-storefront typescript
190
+ GPUOpen-Drivers/llvm c
191
+ kevinclark/indexer go
192
+ Distrotech/intellij-community java
193
+ pburtchaell/react-notification javascript
194
+ rogermelich/Auth php
195
+ amorison/qjobs python
196
+ silvermind/bookyt ruby
197
+ rlustin/lugh rust
198
+ anthonynsimon/parrot typescript
199
+ Smartling/ios-i18n c
200
+ julianec/justanotherircbot go
201
+ googleinterns/step43-2020 java
202
+ ShieldBattery/ShieldBattery javascript
203
+ KRDS/Validator php
204
+ blancltd/blanc-basic-pages python
205
+ Swirrl/digitalsocial ruby
206
+ iankronquist/rustyvisor rust
207
+ kamilmysliwiec/nest typescript
208
+ dancxjo/spell-dollars c
209
+ johnny-morrice/godless go
210
+ prophile/ludum-dare-30 java
211
+ SidKH/angular-starter-kit javascript
212
+ Sheco/cdda-itembrowser php
213
+ zchee/python-client python
214
+ jmfieldman/Mortar ruby
215
+ hwchen/keyring-rs rust
216
+ Anveio/mturk-engine typescript
217
+ webmaster128/botan c
218
+ sluceno/chuper go
219
+ xdrop/PassLock java
220
+ u-wave/hub javascript
221
+ markstory/mini-asset php
222
+ CBitLabs/django-globals python
223
+ jkotests/watir ruby
224
+ nwoeanhinnogaehr/llvm-rs rust
225
+ Kurtz1993/ionic-minify typescript
226
+ JuliaPackageMirrors/ParallelAccelerator.jl c
227
+ robbiev/ui go
228
+ loxal/FreeEthereum java
229
+ elliotaplant/tanks javascript
230
+ TypiCMS/Slides php
231
+ rgardner/ouimeaux python
232
+ project-octopus/octopodes ruby
233
+ rust-gnome/gtk rust
234
+ Jameskmonger/dependument typescript
235
+ nathanielng/code-templates c
236
+ golang/lint go
237
+ oscartu2/magical-kf java
238
+ Dynalon/Rainy javascript
239
+ Ben-Ho/koala-framework php
240
+ hsolbrig/SNOMEDToOWL python
241
+ azumakuniyuki/make-server ruby
242
+ uni-rs/uni.rs rust
243
+ cynicaloptimist/improved-initiative typescript
244
+ bbannier/ROOT c
245
+ go-gl/glfw go
246
+ hpautonomy/java-hod-client java
247
+ Sage/carbon javascript
248
+ swisnl/laravel-fulltext php
249
+ kevinschaul/open-in-github python
250
+ FlavourSys/rails-better-filters ruby
251
+ dskecse/rust_for_rubyists rust
252
+ RenovoSolutions/TypeScript-Angular-Utilities typescript
253
+ SteveCaine/MBTA-RestKit c
254
+ hackedu/website go
255
+ Azure-Samples/documentdb-java-todo-app java
256
+ kylestev/vue-animated-number javascript
257
+ enlim/core php
258
+ TangledWeb/tangled.auth python
259
+ bisscomm/refinerycms-products ruby
260
+ vhbit/lmdb-rs rust
261
+ JosephDuffy/josephduffy.co.uk typescript
262
+ tywkeene/Shell c
263
+ andybalholm/redwood go
264
+ fabiohxcx/socialbooksapi java
265
+ jbmusso/tinkergraph-js javascript
266
+ tastyigniter/TastyIgniter php
267
+ bbangert/retools python
268
+ wecohere/capacitor ruby
269
+ mbrubeck/rust-azure rust
270
+ manuth/MarkdownConverter typescript
271
+ jefbed/xstatus c
272
+ elves/elvish go
273
+ bsalimi/myria java
274
+ sqlectron/sqlectron-gui javascript
275
+ DanCassiano/App php
276
+ czpython/aldryn-faq python
277
+ mzazrivec/manageiq ruby
278
+ oli-obk/rust-pandoc rust
279
+ dolanmiu/docx typescript
280
+ bobrippling/ucc-c-compiler c
281
+ thoughtworks/talisman go
282
+ TeamTotemic/Totemic java
283
+ chiehwen/Node-Exercises javascript
284
+ TeamTyro/teamtyro.com php
285
+ alama/PSO2Proxy python
286
+ fpgentil/toy-robot-simulator ruby
287
+ kylewlacy/glitter rust
288
+ fabianweb/hue typescript
289
+ madf/jwtxx c
290
+ jaceju/go-md go
291
+ eshioji/trident-tutorial java
292
+ chi-bobolinks-2015/TheGoldenRecord javascript
293
+ alexcw234/feyAnthology php
294
+ 10gen-labs/mongo-connector python
295
+ xpsurgery/shopping-cart ruby
296
+ nipunn1313/cargo rust
297
+ log0ymxm/node-harvest typescript
298
+ Zeacone/PlayPlan c
299
+ xgfone/go-tools go
300
+ tmaret/sling java
301
+ Plantia/app javascript
302
+ php-school/php-workshop php
303
+ makinacorpus/reportlab-ecomobile python
304
+ omise/girlscout ruby
305
+ kkawakam/rustyline rust
306
+ codarchlab/idai-field-client typescript
307
+ 8l/ucc-c-compiler c
308
+ brettbuddin/campfire go
309
+ tuxetuxe/pchud java
310
+ flubstep/engvalues javascript
311
+ sampleOmont/quick php
312
+ devinmcgloin/advent python
313
+ kmerz/graveio ruby
314
+ indiv0/ferrum rust
315
+ invicticide/fractive typescript
316
+ appcom-interactive/MFSideMenu c
317
+ rocwong/neko go
318
+ basho/riak-java-client java
319
+ alphagov/static javascript
320
+ chriscohen/codeception-module-drupal-user-registry php
321
+ problemshift/kf5py python
322
+ reuven/modelingcommons ruby
323
+ nafarlee/thoughtfuck rust
324
+ GreenPix/dilia typescript
325
+ llvm-mirror/llvm c
326
+ oipwg/media-protocol go
327
+ cflint/CFLint java
328
+ SputterPuttRedux/storyvine_clone javascript
329
+ vladab/KnpTimeBundle php
330
+ PyO3/setuptools-rust python
331
+ aelogica/express_admin ruby
332
+ dorayakikun/alfred_jira_workflow rust
333
+ sMteX/WoWAnalyzer typescript
334
+ apple/swift-clang c
335
+ SpirentOrion/turnpike go
336
+ premkumarbalu/scsb-etl java
337
+ tmiller/network javascript
338
+ kaltar/Notify php
339
+ apoorvemohan/haas python
340
+ samasti/noosfero ruby
341
+ lyuboraykov/rust-exercises rust
342
+ arangodb/arangojs typescript
343
+ mnunberg/subjson c
344
+ equinox-io/equinox go
345
+ MXProgrammingClub/Chem-Helper java
346
+ sussol/mobile javascript
347
+ DoSomething/messagebroker-ds-PHP php
348
+ crsmithdev/arrow python
349
+ benjaminhyw/ArrayLists ruby
350
+ zummenix/mprovision rust
351
+ zuzusik/DefinitelyTyped typescript
352
+ onkwon/yaos c
353
+ polydawn/repeatr go
354
+ albertoruibal/gwt_android_emu java
355
+ t3b/t3b_template javascript
356
+ Metalaka/Central php
357
+ c4fcm/CLIFF-API-Client python
358
+ DynamoMTL/spree_gateway ruby
359
+ ekarlso/rust-metrics rust
360
+ FountainJS/generator-fountain-react typescript
361
+ jrobhoward/SCADAbase c
362
+ tendermint/tmsp go
363
+ kelemen/JTrim java
364
+ peplin/redmine_create_wiki_page javascript
365
+ nsams/koala-framework php
366
+ martinrusev/imbox python
367
+ PopulateTools/gobierto-dev ruby
368
+ SirRade/sbb-telegram-bot rust
369
+ akserg/ng2-toasty typescript
370
+ aacoppa/final c
371
+ gsamokovarov/jump go
372
+ shengmin/coding-problem java
373
+ holmwell/circle-blvd javascript
374
+ orocrm/platform php
375
+ favien/favien python
376
+ chef-cookbooks/memcached ruby
377
+ andschwa/rust-genetic-algorithm rust
378
+ blackbaud/skyux2 typescript
379
+ tulindanil/SEUIKit c
380
+ dominichamon/gotrace go
381
+ stelar7/L4J8 java
382
+ saurabh6790/frappe javascript
383
+ WellCommerce/CurrencyBundle php
384
+ thomwiggers/django-mongodbforms python
385
+ tablexi/restforce-db ruby
386
+ AndrewBrinker/rust-www rust
387
+ Microsoft/TypeScript typescript
388
+ approach0/search-engine c
389
+ duckbrain/ldss go
390
+ tobiasheine/Movies java
391
+ Mangopay/mangopay2-nodejs-sdk javascript
392
+ robobalasko/OpenEstateAgent php
393
+ anthonysandrin/kafka-utils python
394
+ mlomnicki/rails_event_store ruby
395
+ aetherknight/fractal-rs rust
396
+ XavierGuichet/bemoove-front typescript
397
+ kmuzalewska/j-pet-framework c
398
+ anacrolix/torrent go
399
+ box/mojito java
400
+ janga1997/Patterns javascript
401
+ lenar/assetic php
402
+ dplucenio/heat_diffusion_experiment python
403
+ things23/infoblox_client ruby
404
+ thenyeguy/oxcable rust
405
+ artsy/eigen typescript
406
+ cs50sacramento/source-code-1617 c
407
+ Symantec/Dominator go
408
+ aureliano/e-docs java
409
+ jmeas/gistbook javascript
410
+ bendubuisson/silverstripe-cacheinclude php
411
+ bgyori/bioagents python
412
+ divoxx/ruby-php-serialization ruby
413
+ asomers/mockall rust
414
+ nteract/nteract typescript
415
+ bewuethr/stroustrup_ppp c
416
+ ninchat/ninchat-go go
417
+ blackberry/cordova-blackberry java
418
+ nyc-island-foxes-2016/kiwi-overflow javascript
419
+ webfactorybulgaria/Core php
420
+ plainas/tq python
421
+ kbrock/rubygems.org ruby
422
+ redox-os/kernel rust
423
+ Microsoft/vscode-comment typescript
424
+ swarmer/restnotifier c
425
+ bmorton/deployster go
426
+ helycopternicht/elazarev java
427
+ xdv/gatewayd javascript
428
+ za419/GAMR php
429
+ vesln/robber.py python
430
+ unepwcmc/SAPI ruby
431
+ despawnerer/langid-rs rust
432
+ yuki24/force typescript
433
+ goblint/analyzer c
434
+ ReactiveGo/rx go
435
+ cisco-system-traffic-generator/trex-java-sdk java
436
+ heroku/cli javascript
437
+ zachgibson/thewhitneypaige.com php
438
+ dirn/Simon python
439
+ walle/gas ruby
440
+ Marwes/embed_lang rust
441
+ sysgears/apollo-universal-starter-kit typescript
442
+ wiiudev/pyGecko c
443
+ brightbox/gobrightbox go
444
+ Shyri/long-task-service java
445
+ dennisfrank/patternlab-scaffolding javascript
446
+ wunderkraut/WunderTools php
447
+ plone/plone.server python
448
+ cysjonathan/coursemology2 ruby
449
+ rsertelon/habitat rust
450
+ start/up typescript
451
+ skarnet/s6-rc c
452
+ mattheath/kraken go
453
+ ming13/gambit java
454
+ jdthomas718/ClassRat javascript
455
+ andreas22/omnipay-fasapay php
456
+ lauft/timew-report python
457
+ jurrick/mighty_grid ruby
458
+ rust-av/rust-av rust
459
+ seokju-na/geeks-diary typescript
460
+ rbsexton/sockpuppet c
461
+ k0pernicus/goyave go
462
+ Blackrush/Rocket java
463
+ tum-ase-33/rest-server javascript
464
+ rowanhill/wiremock-php php
465
+ AmiiThinks/amii-tf-nn python
466
+ yous/sawarineko ruby
467
+ ragnese/exercism-rust rust
468
+ Nersent/Wexond typescript
469
+ xNUTs/MIT-Mobile-for-iOS c
470
+ osuripple/api go
471
+ metova/privvy java
472
+ uiheros/react-native-redux-todo-list javascript
473
+ ppy/osu-web php
474
+ ludwiktrammer/django-tagging-autocomplete python
475
+ paulelliott/authem ruby
476
+ aturon/async-benches rust
477
+ shioyang/StatsBar typescript
478
+ htcondor/htcondor c
479
+ mojotech/situation-room go
480
+ KeithYokoma/Amalgam java
481
+ mwilliamson/mammoth.js javascript
482
+ talib570/LazyRecord php
483
+ pyinvoke/invocations python
484
+ rrrene/inch ruby
485
+ graydon/rust rust
486
+ treylon/node-secure-password typescript
487
+ SoylentGraham/libmv c
488
+ captncraig/caddy go
489
+ kierarad/gocd java
490
+ uw-it-aca/myuw javascript
491
+ jdesrosiers/resourceful php
492
+ jaylett/django_exceptional_middleware python
493
+ influitive/markety ruby
494
+ vojtechkral/cargo rust
495
+ gpbl/react-day-picker typescript
496
+ radare/spp c
497
+ magic003/alice go
498
+ stevenpost/beaform java
499
+ sindresorhus/ava javascript
500
+ pollopolea/core php
501
+ nosamanuel/dj-queryset-manager python
502
+ rapid7/metasploit-credential ruby
503
+ daboross/fern-rs rust
504
+ StoDevX/AAO-React-Native typescript
505
+ actinium/cppMatrix c
506
+ antham/envh go
507
+ bink81/java-experiments java
508
+ Orodan/Hilary javascript
509
+ barryvdh/laravel-debugbar php
510
+ ap--/python-oceanoptics python
511
+ key-amb/poloxy ruby
512
+ sourrust/flac rust
513
+ microsoft/vscode typescript
514
+ enverarslan/DataStructures c
515
+ efritz/reception go
516
+ ozwillo/ozwillo-kernel java
517
+ frocher/bnb_app javascript
518
+ jjjjcccjjf/davao-aguilas php
519
+ millerdev/django-nose python
520
+ alcesleo/lasp ruby
521
+ faern/rips rust
522
+ andrerpena/react-mde typescript
523
+ TeamVee-Kanas/android_kernel_samsung_kanas c
524
+ viciious/go-tarantool go
525
+ VKCOM/vk-java-sdk java
526
+ satyavh/meteor-emails javascript
527
+ devmophp/DevmoPHP php
528
+ ssanderson/interface python
529
+ DigitalCurationCentre/roadmap ruby
530
+ cosmo0920/ruroonga_command rust
531
+ AgentME/DefinitelyTyped typescript
532
+ abanaiyan/sniper c
533
+ polydawn/go-sup go
534
+ micheljung/downlords-faf-client java
535
+ i-lateral/silverstripe-stripe-forms javascript
536
+ grrr-amsterdam/garp3 php
537
+ ryanraaum/oldowan.mtdna python
538
+ ctti-clinicaltrials/aact ruby
539
+ rust-lang/miri rust
540
+ influxdata/influxdb typescript
541
+ svn2github/webrtc-Revision-8758 c
542
+ kusabashira/acgen go
543
+ i-net-software/JWebAssembly java
544
+ HPI-Hackathon/find-my-car javascript
545
+ onticsoluciones/nofraud php
546
+ oemof/feedinlib python
547
+ negativetwelve/react-native-lookback ruby
548
+ zonyitoo/bson-rs rust
549
+ DTU-R3/ArloBot typescript
550
+ kenhys/fake-lock-screen-pattern c
551
+ dylanvee/libtorrent-go go
552
+ Aeronica/mxTune java
553
+ medikoo/es5-ext javascript
554
+ Khan/phabricator php
555
+ madmaze/pytesseract python
556
+ thogg4/spree ruby
557
+ SBSTP/rust-igd rust
558
+ blockstack/opendig typescript
559
+ LTD-Beget/dovecot c
560
+ jimmified/jimmify-server go
561
+ mbrossard/cryptonit-cloud java
562
+ mpalourdio/SpringBootAngularHTML5 javascript
563
+ DoSomething/rogue php
564
+ timraasveld/ansible-string-split-filter python
565
+ kstarsinic/homebrew-versions ruby
566
+ google/rrg rust
567
+ ProtonMail/WebClient typescript
568
+ smaccm/camkes-tool c
569
+ weaviate/weaviate go
570
+ parzonka/prm4j java
571
+ serverboards/serverboards javascript
572
+ DerManoMann/acache php
573
+ otknoy/michishiki_api_server python
574
+ eregon/mspec ruby
575
+ copy/v86 rust
576
+ BeSite/jQuery.mmenu typescript
577
+ SiftScience/sift-ios c
578
+ kwagdy/koding-1 go
579
+ steve1rm/busbymovies java
580
+ donlink1/jolliTestSideBar javascript
581
+ christopher-johnson/phabricator php
582
+ alexmilesyounger/ds_basics python
583
+ BinaryMuse/rforce-wrapper ruby
584
+ carols10cents/sassers rust
585
+ ChronusEU/lib-tminus.js typescript
586
+ erwango/zephyr c
587
+ icambridge/gomposer go
588
+ iychoi/biospectra java
589
+ stencila/node javascript
590
+ WWXD/WorldWeb-XD php
591
+ adampiskorski/lpr_poc python
592
+ airslie/renalware-core ruby
593
+ yupferris/rustendo64 rust
594
+ sammydre/ts-for-gjs typescript
595
+ mcschroeder/ghc c
596
+ herald-it/goncord go
597
+ CS2103JAN2017-T16-B4/main java
598
+ nossas/bonde-client javascript
599
+ jordanv215/moparvinson-jordanpwp php
600
+ ranisalt/enigma python
601
+ GCorbel/smart_management ruby
602
+ pgrzesik/learning-rust rust
603
+ crowi/crowi typescript
604
+ royel21/STM32F103GNU c
605
+ 90TechSAS/libgo-docker-guard go
606
+ robolectric/deckard-maven java
607
+ kayaelle/msol-badger javascript
608
+ dadish/ProcessGraphQL php
609
+ infOpen/ansible-role-vsftpd python
610
+ rapid7/sonar-client ruby
611
+ attilahorvath/exercism-rust rust
612
+ Workable/aggregator-eip typescript
613
+ vinamarora8/IAAI c
614
+ madhanrm/hcsshim go
615
+ OpenAMEE/amee.platform.api java
616
+ tomanistor/osprey javascript
617
+ jolantis/altair php
618
+ chubbymaggie/asap python
619
+ riyad/homebrew-cask ruby
620
+ Grieverheart/dsfmt-rs rust
621
+ videogular/videogular2 typescript
622
+ agacek/util_libs c
623
+ nekikara/flagparse go
624
+ nisrulz/android-examples java
625
+ Flieral/Announcer-Service javascript
626
+ borNfreee/tactician-domain-events php
627
+ girder/girder_worker python
628
+ cohei/homebrew-cask ruby
629
+ vickenty/perl-xs rust
630
+ AArnott/Nerdbank.GitVersioning typescript
631
+ showcode/tools c
632
+ Anaminus/rbxmk go
633
+ capergroup/bayou java
634
+ ayrtonvwf/lite-admin javascript
635
+ fashionweb/moraso php
636
+ atiberghien/makerscience-server python
637
+ hakanensari/peddler ruby
638
+ w4tson/early-tea rust
639
+ ashwinr/DefinitelyTyped typescript
640
+ benjic/web-server c
641
+ daemonl/go_lib go
642
+ indr/335 java
643
+ jwadhams/json-logic-js javascript
644
+ tehoko/lane php
645
+ KuChanTung/Python python
646
+ clappr/clappr-ios ruby
647
+ algorithm-ninja/task-wizard rust
648
+ Atyantik/react-pwa typescript
649
+ artem-ogre/simpson c
650
+ cloudfoundry/cli go
651
+ mickkay/MinecraftForge java
652
+ alfredoem/gulp-prelude javascript
653
+ jasny/formbuilder-angular php
654
+ globocom/database-as-a-service python
655
+ hotvulcan/whitehall ruby
656
+ brianp/muxed rust
657
+ unional/ava-fixture typescript
658
+ ecaselles/Kiwi c
659
+ pasinskim/deployments go
660
+ grayben/10K-item-extractor java
661
+ benrowe/laravel-config javascript
662
+ anomalylabs/users-module php
663
+ Stark-Mountain/meetup-facebook-bot python
664
+ Shopify/shipit-engine ruby
665
+ nbigaouette/rust-sorting rust
666
+ mixitconf/mixit typescript
667
+ grigaci/BIObjCHelpers c
668
+ pgombola/gomad go
669
+ core9/module-authentication-standard java
670
+ ecohealthalliance/GoodQuestion javascript
671
+ SlateFoundation/slate php
672
+ claudiopastorini/claudiopastorini.github.io python
673
+ linkedin/cassette ruby
674
+ veorq/oee rust
675
+ Dart-Code/Dart-Code typescript
676
+ conformal/spectrwm c
677
+ tbroyer/ocspd go
678
+ castle/castle-java java
679
+ meisyal/MIM javascript
680
+ Viktor-s/f php
681
+ b123400/purescript-ide-sublime python
682
+ bengler/tiramisu ruby
683
+ BonsaiDen/discord-bot rust
684
+ ecsnavarretemit/sarai-ng2 typescript
685
+ Zaladar/PPM c
686
+ SteelSeries/golisp go
687
+ Techern/carpentersblocks java
688
+ martindale/fabric javascript
689
+ RoboJackets/apiary php
690
+ bshaffer/appengine-python-vm-hello python
691
+ jwt/ruby-jwt ruby
692
+ DualSpark/rust-aws rust
693
+ fqqb/yamcs typescript
694
+ jsventek/Cache c
695
+ rainycape/gondola go
696
+ obidea/semantika-cli2 java
697
+ tightenco/ziggy javascript
698
+ phpgt/webengine php
699
+ chop-dbhi/django-webhooks python
700
+ stanclai/redmine_git_hosting ruby
701
+ mrobinson/rust-layers rust
702
+ dpmcmlxxvi/turf typescript
703
+ skarnet/skalibs c
704
+ irwansyahwii/Pattern-Oriented-Software-Architecture-With-Go go
705
+ FAForever/faf-java-api java
706
+ rafaelstz/regenerator javascript
707
+ scherersoftware/cake-monitor php
708
+ jwarshaw/RaspberryDrive python
709
+ jinutm/silverprod ruby
710
+ aidancully/rust rust
711
+ shlomiassaf/DefinitelyTyped typescript
712
+ Tatsh/libbinarycookies c
713
+ lsk-kun/lantern go
714
+ wbknez/schelling java
715
+ rogierslag/mjml javascript
716
+ IronSummitMedia/startbootstrap-freelancer php
717
+ aikramer2/spaCy python
718
+ patatepartie/local_apt ruby
719
+ Twinklebear/tray_rust rust
720
+ lathonez/clicker typescript
721
+ wistoch/meego-app-browser c
722
+ pachyderm/pfs go
723
+ nearit/Android-SDK java
724
+ trevormunoz/katherine-anne javascript
725
+ APaikens/GoalioForgotPassword php
726
+ alexgarciac/scrapi python
727
+ fgrehm/chef-dokku ruby
728
+ BurntSushi/regexp rust
729
+ raviqqe/code2d typescript
730
+ llvm-mirror/compiler-rt c
731
+ sgeb/go-tuikit go
732
+ thatafischer/feevale-multiuserchat-2015 java
733
+ LLK/scratch-vm javascript
734
+ juriansluiman/SlmQueueBeanstalkd php
735
+ karel-brinda/prophyle python
736
+ stevenhaddox/cookbook-rvm_fw ruby
737
+ OJFord/tapioca rust
738
+ terascope/teraslice typescript
739
+ HenryRLee/PokerHandEvaluator c
740
+ FurqanSoftware/papyrus go
741
+ zafarella/java-design-patterns java
742
+ jpartogi/projexion javascript
743
+ sitkoru/context-cache php
744
+ etataurov/pytest python
745
+ code-management/netrc ruby
746
+ oconnor0/system-zero rust
747
+ driftyco/ionic-cli typescript
748
+ strazzere/dexterity c
749
+ vonwenm/fnlog go
750
+ smithkm/gcs java
751
+ ShawnTe/guardian javascript
752
+ aginev/datagrid php
753
+ khchine5/opal python
754
+ hashicorp/vault-rails ruby
755
+ ddevlin/rustlings rust
756
+ Retrospring/retrospring typescript
757
+ gumpt/cilium c
758
+ Southern/async go
759
+ Slikey/EffectLib java
760
+ c4fcm/Promise-Tracker-Builder javascript
761
+ friendica/friendica php
762
+ hatbot-team/hatbot_resources python
763
+ weddingparty/epicify ruby
764
+ DarkEld3r/match_any rust
765
+ bkimminich/juice-shop typescript
766
+ LiuShulong/Kiwi c
767
+ mistsys/tuntap go
768
+ microsoftgraph/msgraph-sdk-java java
769
+ TrueCar/gluestick javascript
770
+ Programie/AlbumShowcase php
771
+ ellmetha/machina-singlepageapp python
772
+ zettajs/ZettaKit ruby
773
+ jorendorff/cell-gc rust
774
+ orangain/kifu-notebook typescript
775
+ Lavesson/api-mock c
776
+ bragr/dns go
777
+ m4tx/arroch java
778
+ BOZ2323/virun javascript
779
+ cedricziel/l5-shariff php
780
+ seibert/numba python
781
+ CharlesMilam/tatalog ruby
782
+ Laastine/zombie-shooter rust
783
+ gamejolt/widgets typescript
784
+ sjinks/qt_eventdispatcher_epoll c
785
+ janos/httputils go
786
+ cstroe/spendhawk-java java
787
+ Chan4077/angular-rss-reader javascript
788
+ WaveHack/OpenDominion php
789
+ earlwlkr/POICrawler python
790
+ aarongustafson/jekyll-crosspost_to_medium ruby
791
+ wahn/Rust_Examples rust
792
+ graywolf336/temporary-rocketlets-ts-definition typescript
793
+ LuboO/iCalendar-parser_PA193_Rteam c
794
+ mmstick/i3gostatusbar go
795
+ DarkMorford/BetterThanWeagles java
796
+ wycats/blue-ridge javascript
797
+ marcoraddatz/activecollab-slack php
798
+ ideascube/ideascube python
799
+ cosmo0920/homebrew-cask-coreclr ruby
800
+ rust-fuzz/cargo-fuzz rust
801
+ the-concierge/concierge typescript
802
+ saminiir/level-ip c
803
+ dpb587/metalink go
804
+ AdamsTHDev/mgl-planlv-project java
805
+ getfrank/tachyons javascript
806
+ mb-projects/mbtheme-mtalents php
807
+ group-policy/rally python
808
+ tsuru/homebrew-tsuru ruby
809
+ danylaporte/node-rust-resemble rust
810
+ 2muchcoffeecom/ngx-restangular typescript
811
+ HPCToolkit/hpctoolkit c
812
+ cloudfoundry/staticfile-buildpack go
813
+ gernd/simple-site-mon java
814
+ keybase/client javascript
815
+ WyriHaximus/TwigView php
816
+ funkybob/paws python
817
+ travis-ci/packer-templates ruby
818
+ Sgeo/hlist rust
819
+ ikr/react-period-of-stay-input typescript
820
+ biosbits/libffi c
821
+ jimthematrix/fabric go
822
+ billy93/forplay java
823
+ zdfs/bliss javascript
824
+ Exercise/FOQElasticaBundle php
825
+ analyst-collective/dbt python
826
+ thecartercenter/elmo ruby
827
+ google/tock-on-titan rust
828
+ NakedObjectsGroup/NakedObjectsFramework typescript
829
+ leapmotion/autowiring c
830
+ cerana/cerana go
831
+ ganymedes01/Et-Futurum java
832
+ Dermah/pulsar javascript
833
+ nachopro/followlink php
834
+ scanner-research/scanner python
835
+ amatriain/feedbunch ruby
836
+ jpypi/rustix rust
837
+ ruedap/alfred-font-awesome-workflow typescript
838
+ Tricertops/Objective-Chain c
839
+ brandur/sorg go
840
+ balazspete/crystal-game java
841
+ marynganga/FunSquare javascript
842
+ naturalsciences/Darwin php
843
+ ScanOC/trunk-player python
844
+ qnyp/smiling ruby
845
+ dpc/slog-rs rust
846
+ slackapi/node-slack-sdk typescript
847
+ dmtaylor/cmps111-proj4 c
848
+ oshothebig/goflow go
849
+ MC-U-Team/U-Team-Core java
850
+ bbcyyb/on-tasks javascript
851
+ dilawar/ncbs-minion php
852
+ saltstack/salt python
853
+ yumingjuan/selenium ruby
854
+ emk/credentials rust
855
+ jsse-2017-ph23/web-frontend typescript
856
+ yamnikov-oleg/cgo-callback c
857
+ hajimehoshi/ebiten go
858
+ boundary/meter-plugin-sdk-java java
859
+ Darkrender/raptor-ads javascript
860
+ graphp/plaintext php
861
+ cherba/apitools python
862
+ theodi/csvlint ruby
863
+ Wandalen/wTools rust
864
+ romancow/ts-geometry typescript
865
+ simonpf/root c
866
+ golang/appengine go
867
+ jahed/crowd-play java
868
+ megos/asagao javascript
869
+ Pikkulahti/leijonaa php
870
+ RainCity471/lyCompiler python
871
+ crowdAI/crowdai ruby
872
+ owaspjocur/servo rust
873
+ KamiKillertO/vscode-colorize typescript
874
+ bloom-lang/c4 c
875
+ F5Networks/k8s-bigip-ctlr go
876
+ gramboid/RxAppFocus java
877
+ ajacksified/reddit-mobile javascript
878
+ stratedge/passport-facebook php
879
+ chiphogg/vim-vtd python
880
+ ManageIQ/manageiq-ui-classic ruby
881
+ magum/rust-rosetta rust
882
+ google/chicago-brick typescript
883
+ jamespearce2006/CefSharp c
884
+ wickedchicken/dwd-go go
885
+ NUBIC/psc-mirror java
886
+ iTerminate/traveler javascript
887
+ phoenixgao/laravel-postgres-extended-schema php
888
+ patrickspencer/mathdeck python
889
+ iiet/iiet-git ruby
890
+ raineszm/rust-blas rust
891
+ tsg-ut/slackbot typescript
892
+ nickolasburr/git-stashd c
893
+ mrekucci/epi go
894
+ apache/commons-jexl java
895
+ RakanNimer/react-google-charts javascript
896
+ garciaf/fabbook php
897
+ brainwane/zulip python
898
+ svcastaneda/phase-0 ruby
899
+ kkimdev/autograd rust
900
+ wiktor-k/infrastructure-tests typescript
901
+ Payshare/libsodium c
902
+ thaJeztah/distribution go
903
+ nulab/zxcvbn4j java
904
+ FleetOnRails/fleet-web-app javascript
905
+ danielsan80/MeasureBundle php
906
+ handroll/handroll python
907
+ thoughtbot/neat ruby
908
+ d-unseductable/ruru rust
909
+ deegles/cookietime typescript
910
+ DDVTECH/mistserver c
911
+ chadev/Chadev_ircbot go
912
+ benmfaul/XRTB java
913
+ tddbin/tddbin-frontend javascript
914
+ tailwindlabs/tailwindcss php
915
+ sl2017/campos python
916
+ teeparham/gemdiff ruby
917
+ servo/rust-http rust
918
+ SimonSchick/EliteDangerousUtils typescript
919
+ Kromey/roglick c
920
+ ninjasphere/hc go
921
+ EBIBioSamples/biosamples-v4 java
922
+ worldbank-cdrp/disaster-risk-explorer javascript
923
+ wowtransfer/chdphp php
924
+ wiliamsouza/hystrix-py python
925
+ eventide-project/log ruby
926
+ godcoin/godcoin rust
927
+ jovotech/jovo-framework-nodejs typescript
928
+ dawehner/root c
929
+ ewbankkit/terraform go
930
+ ablenesi/ELTEProjectToolsTeam09 java
931
+ RaphaelDeLaGhetto/gebo-registrant-hai javascript
932
+ tonightsystems/alf-cms php
933
+ dimagi/commcare-hq python
934
+ solidusio-contrib/solidus_subscriptions ruby
935
+ cosmo0920/ruroonga rust
936
+ michaelbull/zoom.ts typescript
937
+ shockkolate/shockk-os c
938
+ google/mtail go
939
+ SOM-st/black-diamonds java
940
+ codeforamerica/streetmix javascript
941
+ simplesamlphp/simplesamlphp-module-openid php
942
+ thiderman/network-kitten python
943
+ jspizziri/spree ruby
944
+ WPO-Foundation/gnirehtet rust
945
+ emugaya/bucketlist_frontend typescript
946
+ wnh/prompt_utils c
947
+ photoshelf/photoshelf-storage go
948
+ CS2103AUG2016-W14-C1/main java
949
+ skidding/flatris javascript
950
+ WeMoveEU/bsd_api php
951
+ kefir500/ghstats python
952
+ adamthedeveloper/wepay-rails ruby
953
+ skade/leveldb rust
954
+ gluons/font-awesome-openui5 typescript
955
+ muxi/grpc c
956
+ keep94/Dominator go
957
+ c-rack/czmq java
958
+ gefs-plugins/fmc-requirejs javascript
959
+ symfony/HttpKernel php
960
+ JungeAlexander/cocoscore python
961
+ key-amb/fireap ruby
962
+ gyn/exercism rust
963
+ Discordius/Lesswrong2 typescript
964
+ adobe/chromium c
965
+ mtibben/confusables go
966
+ mgenov/sitebricks java
967
+ kiwiirc/irc-framework javascript
968
+ swt83/php-inline php
969
+ ohsu-qin/qipipe python
970
+ railsmachine/lita-ext ruby
971
+ anthgur/servo rust
972
+ mike-north/ember-api-actions typescript
973
+ AppliedLogicSystems/ALSProlog c
974
+ materials-commons/mcstore go
975
+ phoenixnudt/OWL2VOWL java
976
+ EricCat/Node-File-Delete javascript
977
+ beberlei/AzureDistributionBundle php
978
+ sergey-dryabzhinsky/dedupsqlfs python
979
+ eloy/debox_server ruby
980
+ erickt/cargo rust
981
+ GoogleChrome/web-vitals typescript
982
+ thinnect/tos-groundlib c
983
+ orifinkelman/incubator-trafficcontrol go
984
+ imCodePartnerAB/iVIS java
985
+ imiric/usearch javascript
986
+ facilis/users php
987
+ t-miyamae/teuthology python
988
+ vinsol/Spree-Unified-Payments ruby
989
+ hackndev/zinc rust
990
+ opennode/waldur-homeport typescript
991
+ groonga/groonga c
992
+ cloudfoundry-incubator/runtime-schema go
993
+ dhanji/sitebricks java
994
+ jeremyruppel/vmplate javascript
995
+ VitSalis/endofcodes php
996
+ 0xPoly/ooni-probe python
997
+ frc-frecon/frecon ruby
998
+ kassens/relay rust
999
+ faddiv/budget-keeper typescript
1000
+ eaburns/pbnf c
1001
+ yorickdewid/gocraw go
1002
+ davido/gerrit-reviewers-plugin java
1003
+ dollarshaveclub/ember-cli-anybar javascript
1004
+ sgmendez/example_api_rest php
1005
+ sorgerlab/indra python
1006
+ bugsnag/bugsnag-js ruby
1007
+ mhallin/juniper rust
1008
+ drumonii/LeagueTrollBuild typescript
1009
+ PeterWangIntel/chromium-crosswalk c
1010
+ abiosoft/ishell go
1011
+ fimtra/datafission java
1012
+ pipedrive/client-nodejs javascript
1013
+ evanmaastrigt/kwetal-workdays php
1014
+ nvbn/thefuck python
1015
+ fureigh/change-my-record ruby
1016
+ serde-rs/serde rust
1017
+ Alfresco/alfresco-ng2-components typescript
1018
+ joel-porquet/tsar-uclibc c
1019
+ owulveryck/google-app-example go
1020
+ groupon/Selenium-Grid-Extras java
1021
+ kpdecker/next.js javascript
1022
+ million12/M12.Foundation php
1023
+ aosp-mirror/platform_external_skia python
1024
+ leonid-shevtsov/knife-solo ruby
1025
+ edunham/regex rust
1026
+ mollie/mollie-api-node typescript
1027
+ utahiosmac/Marshal c
1028
+ vektorlab/otter go
1029
+ repeats/Repeat java
1030
+ benjamn/offgrid-lights javascript
1031
+ OParl/dev-website php
1032
+ masasin/spirit python
1033
+ nurelm/quickbooks_integration ruby
1034
+ warricksothr/dft rust
1035
+ endeavourhealth/EDS typescript
1036
+ iTermin/app_iOS c
1037
+ shiena/go-gitbucket go
1038
+ philippsied/smartcard-course java
1039
+ vekat/vcat javascript
1040
+ M2Mobi/lunr php
1041
+ benedicteb/outcast python
1042
+ ashrafuzzaman/stips ruby
1043
+ stewart/rff rust
1044
+ debugworkbench/hydragon typescript
1045
+ aaronmjacobs/openal-soft c
1046
+ mgutz/logxi go
1047
+ shineM/gh4a java
1048
+ TarrinRos/PizzaShop javascript
1049
+ vrap/project-b php
1050
+ SEL-Columbia/commcare-hq python
1051
+ thredup/sidekiq-grouping ruby
1052
+ corragon/rust-raytracer rust
1053
+ madigan/ncounter-ng2 typescript
1054
+ cdzombak/thingshub c
1055
+ l1jiang/govmomi go
1056
+ pivotal-bank/portfolio-service java
1057
+ sblask/firefox-open-tabs-next-to-current javascript
1058
+ hiqdev/hipanel-module-finance php
1059
+ OCA/stock-logistics-warehouse python
1060
+ jmespath/jmespath.rb ruby
1061
+ philyoon/rust rust
1062
+ V-Paranoiaque/Ellas-War typescript
1063
+ FreeScienceCommunity/PLPlot c
1064
+ v2tec/watchtower go
1065
+ UweTrottmann/thetvdb-java java
1066
+ indexzero/read-ssl javascript
1067
+ Clidus/dumplog-website php
1068
+ lemming52/white_knight python
1069
+ SvetoslavKuzmanov/asteroids ruby
1070
+ dcuddeback/libudev-rs rust
1071
+ citizenlabsgr/voter-engagement typescript
1072
+ aldebaran/libport c
1073
+ ghmeier/coinage go
1074
+ codecop/ugly-trivia-kata java
1075
+ fernandocanizo/choodo javascript
1076
+ axton21/voting-app php
1077
+ egafford/sahara python
1078
+ Joel-B-Williams/Meandr ruby
1079
+ saulius/croaring-rs rust
1080
+ jacobjojan/angular2-webpack-starter typescript
1081
+ tomdev2008/energy c
1082
+ DataDog/go-datadog-api go
1083
+ devhub-tud/devhub-prototype java
1084
+ nicolasmccurdy/procrastinate javascript
1085
+ DoSomething/aurora php
1086
+ jdevera/subdue python
1087
+ mbj/axiom-arango-adapter ruby
1088
+ dbrodie/rex rust
1089
+ davidsidlinger/DefinitelyTyped typescript
1090
+ shahedmolla/test c
1091
+ eriol/piken go
1092
+ kashike/SpongeAPI java
1093
+ ForbesLindesay/thread-sleep javascript
1094
+ michaelletzgus/nextcloud-server php
1095
+ VirusTotal/misp-modules python
1096
+ page-io/middleman-s3_sync ruby
1097
+ dwillmer/rust rust
1098
+ devonzuegel/clarity typescript
1099
+ iree-org/iree c
1100
+ mmcgrana/pg2librato go
1101
+ Gamealition/SignShopExport java
1102
+ acingraham/AwwFrame javascript
1103
+ lwiesel/delivery-tracking php
1104
+ benedfit/SublimeLinter-contrib-pug-lint python
1105
+ NYULibraries/rooms ruby
1106
+ pnkfelix/mon-artiste rust
1107
+ DAXaholic/vscode-edifact typescript
1108
+ redforks/thermostat c
1109
+ albfan/gdblib go
1110
+ OpenMods/OpenPeripheral-Addons java
1111
+ IonicaBizau/arc-assembler javascript
1112
+ xemlock/htmlpurifier-html5 php
1113
+ thebinarypenguin/SublimeLinter-contrib-raml-cop python
1114
+ osu-cascades/ecotone-web ruby
1115
+ ruma/ruma rust
1116
+ PakL/TTVStreamerTool typescript
1117
+ reeFridge/learn-oop-through-cpp c
1118
+ revl/autoforge go
1119
+ joonhocho/react-native-linkedin-sdk java
1120
+ roschaefer/rundfunk-mitbestimmen javascript
1121
+ hardywen/captcha php
1122
+ csrocha/account_journal_payment_subtype python
1123
+ yeban/sequenceserver ruby
1124
+ GBGamer/rust rust
1125
+ ikatyang/dts-element typescript
1126
+ atropelando/terceiro-ano-programacao c
1127
+ strivecast/hcl go
1128
+ VisualDataWeb/OntoBench java
1129
+ Leko/WEB-EGG javascript
1130
+ bearsunday/BEAR.Resource php
1131
+ pombreda/seascope python
1132
+ hpcloud/unix_cli ruby
1133
+ iKevinY/ultra rust
1134
+ ravendb/ravendb-nodejs-client typescript
1135
+ Roadagain/Calculator c
1136
+ luci/luci-go go
1137
+ NCIP/psc java
1138
+ joaquindev/learning-mongoose javascript
1139
+ aalfiann/reSlim php
1140
+ tanayseven/personal_website python
1141
+ teespring/envm ruby
1142
+ amongil/bluenine rust
1143
+ edhager/widget-core typescript
1144
+ elupus/osek c
1145
+ 1and1/soma go
1146
+ Enoro/commons-compress java
1147
+ firebug/firebug.next javascript
1148
+ Sylius/Cart php
1149
+ pinry/pinry python
1150
+ mthssdrbrg/kafka-cookbook ruby
1151
+ ConnyOnny/Cursive-Break rust
1152
+ grafana/grafana typescript
1153
+ honux77/practice c
1154
+ phalaaxx/ratemilter go
1155
+ snowble/vertical-stepper java
1156
+ pinittome/proxy javascript
1157
+ romhut/criterion php
1158
+ geelweb/laposte-python-sdk python
1159
+ opscode-cookbooks/partial_search ruby
1160
+ fabianschuiki/moore rust
1161
+ fsahmad/tsuml-demo typescript
1162
+ mihaimaruseac/dphcar c
1163
+ billhathaway/webcounter go
1164
+ Mahtimursut/ohtu java
1165
+ webkom/eslint-config-webkom javascript
1166
+ app-zap/PHPFramework php
1167
+ phil-lopreiato/the-blue-alliance python
1168
+ bdunne/manageiq-automation_engine ruby
1169
+ bpowers1215/MoneyMap rust
1170
+ Picturepark/Picturepark.SDK.TypeScript typescript
1171
+ barbagroup/cuIBM c
1172
+ pierrre/mangadownloader go
1173
+ UweTrottmann/trakt-java java
1174
+ franvarney/franvarney-api javascript
1175
+ Parabot/BDN-V3 php
1176
+ EnvGen/toolbox python
1177
+ gocardless/que ruby
1178
+ dtolnay/thiserror rust
1179
+ spinnaker/deck typescript
1180
+ Lightricks/ocmock c
1181
+ bdastur/utils go
1182
+ bdezonia/zorbage java
1183
+ georapbox/jsEssentials javascript
1184
+ Lecturize/Laravel-Taxonomies php
1185
+ openaustralia/publicwhip-matthew python
1186
+ KarmaHater/WikiEduDashboard ruby
1187
+ Ticki/libterm rust
1188
+ denismaster/dcs typescript
1189
+ nadirs/dmgemu c
1190
+ nono/cozy-stack go
1191
+ Ullink/slack4gerrit java
1192
+ agustim/fiberfy-server javascript
1193
+ RhubarbPHP/Website php
1194
+ thorgate/django-project-template python
1195
+ ontohub/ontohub ruby
1196
+ mbrubeck/servo rust
1197
+ sanity-io/sanity typescript
1198
+ tjarratt/twIRCk c
1199
+ oftc-ftw/stove go
1200
+ elBukkit/MagicPlugin java
1201
+ wh1tney/recordly javascript
1202
+ okulbilisim/ojs php
1203
+ monostable/haskell-kicad-data python
1204
+ theresaboard/theres-a-board ruby
1205
+ tempbottle/ProjectEulerRust rust
1206
+ third774/ng-bootstrap-form-validation typescript
1207
+ btrask/hash-archive c
1208
+ rgooch/Dominator go
1209
+ xkrogen/gobblin java
1210
+ Syncano/syncano-dashboard javascript
1211
+ digitalkaoz/BetterReflection php
1212
+ OpenSpace/OpenSpace python
1213
+ obsidian-btc/data-aggregation-index ruby
1214
+ zaeleus/rust rust
1215
+ hansl/devkit typescript
1216
+ Chase-san/libspec c
1217
+ ying32/govcl go
1218
+ fabzo/kraken java
1219
+ eamonnbell/sortzzi javascript
1220
+ guzzle/guzzle3 php
1221
+ planetlabs/datalake-ingester python
1222
+ deathwish/absinthe ruby
1223
+ shepmaster/sxd-rust rust
1224
+ minestarks/TypeScript typescript
1225
+ sbc100/native_client c
1226
+ wanelo/image-server go
1227
+ mysangle/algorithm-study java
1228
+ yannickglt/esreflect javascript
1229
+ GeneaLabs/Phpgmaps php
1230
+ yamatt/bonfiremanager python
1231
+ integrallis/stripe_event ruby
1232
+ ThomasColliers/age-of-rust rust
1233
+ hychen/ke-e typescript
1234
+ postmodern/libBERT c
1235
+ liggitt/osin go
1236
+ klausw/hackerskeyboard java
1237
+ albburtsev/talaria javascript
1238
+ Shopify/theme-sync php
1239
+ wkentaro/chainer python
1240
+ Shopify/Hermann ruby
1241
+ stepancheg/rust-protobuf rust
1242
+ BillWagner/TypeScriptAngular2 typescript
1243
+ JFLarvoire/SysToolsLib c
1244
+ jacobsa/aws go
1245
+ watsonarw/twu-biblioteca-andrewwatson java
1246
+ Calvin-Huang/LiveAPIExplore-Server javascript
1247
+ kicks-app/kicks-app-wordpress php
1248
+ Dybov/real_estate_agency python
1249
+ satoryu/tepco_usage_api ruby
1250
+ shssoichiro/oxipng rust
1251
+ Team-CHAD/DevDecks typescript
1252
+ chaoran/fast-wait-free-queue c
1253
+ ninjasphere/go-openzwave go
1254
+ duckAsteroid/osgi-test java
1255
+ mfgea/grunt-dredd javascript
1256
+ Sylius/Currency php
1257
+ Astroua/aws_controller python
1258
+ henrinormak/NSDateComponents-HNExtensions ruby
1259
+ l1048576/fbx_direct rust
1260
+ kulshekhar/ts-jest typescript
1261
+ Juniper/libslax c
1262
+ cortesi/devd go
1263
+ edaubert/jongo java
1264
+ rubenv/grunt-mkdir javascript
1265
+ ku2ma2/design_pattern php
1266
+ nagilum/script.rndmov python
1267
+ mission-of-mercy/momma_dashboard ruby
1268
+ servo/sharegl rust
1269
+ misoukrane/did-or-wish typescript
1270
+ Herbstein/kernel-of-truth c
1271
+ gcapizzi/moka go
1272
+ n-zeplo/TW101_Exercises java
1273
+ edi9999/jsqrcode javascript
1274
+ DoSomething/northstar php
1275
+ lsgunth/rapidsms python
1276
+ srcclr/commit-watcher ruby
1277
+ knsd/from-ascii rust
1278
+ christophd/citrus-admin typescript
1279
+ BeImprovised/gambit c
1280
+ cloudfoundry-community/asp.net5-buildpack go
1281
+ sormuras/bach java
1282
+ thatPamIAm/weathrly javascript
1283
+ mantisbt-plugins/source-integration php
1284
+ yeasy/robot_tool python
1285
+ mkllnk/openfoodnetwork ruby
1286
+ amhk/lokatt rust
1287
+ lit/lit.dev typescript
1288
+ telefonicaid/fiware-cosmos-platform c
1289
+ QuentinPerez/scaleway-cli go
1290
+ cloudfoundry/cf-java-client java
1291
+ WhitestormJS/whs.js javascript
1292
+ Korko/SecretSanta.fr php
1293
+ ShivamSarodia/ShivyC python
1294
+ insight-meditation-center/imc-bootstrap-sass ruby
1295
+ benstreb/astroids-rust rust
1296
+ rishii7/vscode typescript
1297
+ timkettering/SwitecX25 c
1298
+ containers/storage go
1299
+ freeVM/freeVM java
1300
+ stuartkeith/webaudiosequencer javascript
1301
+ nordsoftware/yii-paytrail php
1302
+ stefanklug/plata python
1303
+ daynix/rebuild ruby
1304
+ nickbabcock/boxcars rust
1305
+ DSI-HUG/dejajs-components typescript
1306
+ Luminarys/synapse c
1307
+ celrenheit/lion go
1308
+ bitcoin-solutions/multibit-hd java
1309
+ Brightspace/jquery-valence-ui-more-less javascript
1310
+ DarvinStudio/darvin-utils php
1311
+ willdavidc/piel python
1312
+ knapo/jquery-colorbox-rails ruby
1313
+ kmcallister/rust rust
1314
+ crdschurch/crds-signin-checkin typescript
1315
+ coreux/liberrno c
1316
+ donatj/explainer go
1317
+ smartcommunitylab/sco.carpooling java
1318
+ myntra/react-native javascript
1319
+ jordandukart/islandora_xacml_editor php
1320
+ henriquebastos/virtualenv-bootstrap python
1321
+ chrisfinazzo/homebrew-core ruby
1322
+ lipanski/trello-rs rust
1323
+ yysun/apprun typescript
1324
+ lglucin/Halide c
1325
+ dotcominternet/platform go
1326
+ matco/simcity java
1327
+ jackrzhang/boardsession javascript
1328
+ SolidInvoice/SolidInvoice php
1329
+ ianfieldhouse/number_to_words python
1330
+ vaneyckt/Jently ruby
1331
+ dtolnay/syn rust
1332
+ thenickreynolds/popcorngif typescript
1333
+ duckinator/boreutils c
1334
+ lukevers/go-and-hack go
1335
+ benbenw/jmeter java
1336
+ ufocoder/redux-universal-boilerplate javascript
1337
+ wiltosoft/laravel php
1338
+ sindrig/spoppy python
1339
+ k0kubun/specinfra ruby
1340
+ Gyscos/Cursive rust
1341
+ webcomponents/polyfills typescript
1342
+ GNOME/libchamplain c
1343
+ landonia/landotube go
1344
+ zsoltii/dss java
1345
+ proglottis/oyster javascript
1346
+ jonuy/dosomething php
1347
+ rlee287/pyautoupdate python
1348
+ alphagov/publishing-api ruby
1349
+ am0d/rust-projects rust
1350
+ yadomi/lastagram typescript
1351
+ zwaldowski/AZCoreRecord c
1352
+ kalafut/finiki go
1353
+ Ghostlyr/MinecraftForge java
1354
+ TheLudd/unary javascript
1355
+ KnpLabs/KnpRadBundle php
1356
+ bharling/django-pint python
1357
+ TechnoGate/contao ruby
1358
+ Nicoretti/xxd-rs rust
1359
+ notbakaneko/osu-web typescript
1360
+ syscoin/syscoin c
1361
+ mingrammer/go-codelab go
1362
+ miguel250/Robotics java
1363
+ gldraphael/chordsheet javascript
1364
+ benignware/wp-bootstrap-hooks php
1365
+ jackromo/RandTerrainPy python
1366
+ stephenbm/chef-server ruby
1367
+ jimmycuadra/rust-etcd rust
1368
+ pbraunstein/trackercise typescript
1369
+ digama0/lean c
1370
+ groob/micromdm go
1371
+ DBCG/cql_measure_processor java
1372
+ emberjs/ember-legacy-controllers javascript
1373
+ silverorange/swat php
1374
+ ayushgoel/LongShot python
1375
+ danielfarrell/common_event_formatter ruby
1376
+ jinnjuice/solicit rust
1377
+ FernCreek/tinymce typescript
1378
+ dpt/Containers c
1379
+ schmichael/metafora go
1380
+ jypma/lambda-behave java
1381
+ burninggarden/pirc javascript
1382
+ silverstripe-labs/silverstripe-environmentcheck php
1383
+ reedstrm/Pyrseas python
1384
+ zoocasa/geos-extensions ruby
1385
+ Stebalien/udev-rs rust
1386
+ kdechant/eamon typescript
1387
+ svn2github/libpqxx c
1388
+ maxamillion/flamingo go
1389
+ Addepar/buck java
1390
+ fi-ksi/web-frontend javascript
1391
+ eustasy/browning-a-mailgun-script php
1392
+ andylytical/brewpi-scripts python
1393
+ milewdev/power ruby
1394
+ ron-rs/ron rust
1395
+ ryanluker/vscode-coverage-gutters typescript
1396
+ Atom058/ArduinoLithiumCharger c
1397
+ FriendlyLinuxPlayers/flip.earth go
1398
+ hal/elemento java
1399
+ sauravmndl/service-fabrik-broker javascript
1400
+ nordsoftware/lumen-doctrine php
1401
+ HHS-IntroProgramming/Multiplication-table python
1402
+ lpichler/manageiq ruby
1403
+ kkirstein/hdf5-rs rust
1404
+ upfluence/oss-components typescript
1405
+ llvm-mirror/libcxx c
1406
+ aabizri/navitia go
1407
+ CRollin/ptiChat java
1408
+ gocd/gocd.github.io javascript
1409
+ pantheon-systems/cli php
1410
+ wyager/IHaskell python
1411
+ leandroo/flexi_generators ruby
1412
+ ebfe/syscall.rs rust
1413
+ looker-open-source/embed-sdk typescript
1414
+ dscho/dovecot c
1415
+ walac/taskcluster-worker go
1416
+ JetBrains/teamcity-azure-plugin java
1417
+ khwang/plum javascript
1418
+ bar5z6/swe2015groupl php
1419
+ opnfv/functest python
1420
+ gocardless/business ruby
1421
+ carols10cents/adventofcode-rs rust
1422
+ easyfuckingpeasy/chrome-reddit-comment-highlights typescript
1423
+ jeremiedecock/snippets c
1424
+ gu-bin/bosh-agent go
1425
+ iEli2tyree011/EllyCheat java
1426
+ mstange/cleopatra javascript
1427
+ Piou-piou/ribs-framework php
1428
+ amolenaar/gaphor python
1429
+ abenson/sweep ruby
1430
+ Armavica/99-Problems-Rust rust
1431
+ fvilers/angular2-training typescript
1432
+ plast-lab/cclyzer c
1433
+ delta24/gist go
1434
+ trivago/Heimdall.droid java
1435
+ henrikra/gym-diary javascript
1436
+ meng-tian/php-soap-interpreter php
1437
+ potatolondon/contentious python
1438
+ chefspec/chefspec ruby
1439
+ olajep/gcc-explorer rust
1440
+ ghidello/cli typescript
1441
+ talk-to/Chocolate c
1442
+ mrtazz/checkmake go
1443
+ CCI-MIT/XCoLab java
1444
+ fbaumgardt/arethusa javascript
1445
+ TypiCMS/Pages php
1446
+ pavel-paulau/perfrunner python
1447
+ labocho/action_mailer_config ruby
1448
+ martica/rusty rust
1449
+ guyellis/plant-image-lambda typescript
1450
+ ycaihua/skim-app c
1451
+ carlmjohnson/junix go
1452
+ havarunner/havarunner java
1453
+ cyberkoi/discourse-spoiler-alert javascript
1454
+ freephile/qb php
1455
+ AlexHill/mezzanine python
1456
+ ddrmanxbxfr/active_fulfillment ruby
1457
+ termoshtt/ndarray-linalg rust
1458
+ wikimigrate/wikimigrate typescript
1459
+ zhuhaow/libnekit c
1460
+ khlieng/name_pending go
1461
+ StubbornJava/StubbornJava java
1462
+ mtheoryx/react-redux-es6 javascript
1463
+ boonex/trident php
1464
+ sassoftware/mint python
1465
+ zuku/bmff ruby
1466
+ mcarton/rust-plague rust
1467
+ hjobrien/desktop typescript
1468
+ vidya-ranganathan/algorithms c
1469
+ brooklyncentral/brooklyn-cli go
1470
+ ESSICS/org.csstudio.display.builder java
1471
+ publiclab/Leaflet.DistortableImage javascript
1472
+ mcrumm/phlack php
1473
+ hackerspace-ntnu/website python
1474
+ rohanpm/rcov-cobertura ruby
1475
+ djc/askama rust
1476
+ richmondwang/string-to-obj typescript
1477
+ yusuga/YSProcessTimer c
1478
+ sstark/droguedrums go
1479
+ pentaho/pentaho-commons-xul java
1480
+ foam-framework/foam2 javascript
1481
+ mpociot/reauthenticate php
1482
+ paylogic/py2deb python
1483
+ Schniz/mail ruby
1484
+ cjgreenaway/rubbem rust
1485
+ harksys/HawkEye typescript
1486
+ eikel/EScript c
1487
+ mewkiz/flac go
1488
+ queshaw/dita-ot java
1489
+ tijmenb/spotlight javascript
1490
+ MelcherSt/HTweb php
1491
+ oliverlee/antlia python
1492
+ gmcculloug/sprint_statistics ruby
1493
+ sacherjj/rust rust
1494
+ DeborahK/Angular-Routing typescript
1495
+ Staance/tailproduce c
1496
+ life1347/fission go
1497
+ spring-cloud/spring-cloud-cloudfoundry-service-broker java
1498
+ 1flow/1flow javascript
1499
+ symphonists/markdown_typography php
1500
+ voer-platform/vp.repo python
1501
+ greg5green/homebrew-cask ruby
1502
+ yinyanlv/runner rust
1503
+ storybooks/storybook typescript
1504
+ dafrito/alpha c
1505
+ alecthomas/chroma go
1506
+ mrdon/SAL java
1507
+ Cwejman/martina javascript
1508
+ ansendu/php-libevent php
1509
+ exekias/django-achilles python
1510
+ nju520/pry ruby
1511
+ SirRade/homepage rust
1512
+ dotCMS/dotJS typescript
1513
+ globbie/knowdy c
1514
+ ibrt/go-oauto go
1515
+ realityforge/arez java
1516
+ materials-commons/materialscommons.org javascript
1517
+ kubernetes/examples php
1518
+ ikaruswill/vector-space-model python
1519
+ empirical-org/Empirical-Core ruby
1520
+ cuviper/rayon rust
1521
+ michaelgira23/MyMICDS-v2 typescript
1522
+ chmorgan/libesphttpd c
1523
+ miketheprogrammer/go-thrust go
1524
+ ChestShop-authors/ChestShop-3 java
1525
+ schaui6/yodalize javascript
1526
+ wappr/digitalocean php
1527
+ goldmann/docker-scripts python
1528
+ CannyFoxx/gallery ruby
1529
+ Nukesor/Pueue rust
1530
+ googleinterns/step250-2020 typescript
1531
+ coldfix/setcapslock c
1532
+ grooveshark/golib go
1533
+ codenvy/plugin-datasource java
1534
+ qgrid/ng javascript
1535
+ emgiezet/errbitPHP php
1536
+ tzengyuxio/python-five91 python
1537
+ eregon/rubyspec ruby
1538
+ eqrion/cbindgen rust
1539
+ MurhafSousli/ng2-sharebuttons typescript
1540
+ eingaeph/pip.imbue.hood c
1541
+ kyleterry/tenyks go
1542
+ braintree/braintree_android java
1543
+ substance/texture javascript
1544
+ cachethq/Laravel-Segment php
1545
+ Doist/todoist-python python
1546
+ Pitt-CSC/handy ruby
1547
+ ratel-rust/ratel-server rust
1548
+ hasman16/rent-a-ref typescript
1549
+ Billy4195/Simple_Chatroom c
1550
+ instana/golang-sensor go
1551
+ perdona/titanium_mobile java
1552
+ tenevdev/beacon-valley-hackathon javascript
1553
+ stdtabs/phptabs php
1554
+ datasciencebr/serenata-toolbox python
1555
+ pvalena/rails ruby
1556
+ matt-thomson/github-sweep rust
1557
+ mustpax/sortmybox typescript
1558
+ lefou/kdepim-noakonadi c
1559
+ barnardb/nomad go
1560
+ mohamad-z/dnsjava java
1561
+ MyPureCloud/skype-for-business-purecloud-app javascript
1562
+ orchestral/resources php
1563
+ jeanmask/opps-admin python
1564
+ hubert/comptroller ruby
1565
+ LukasKalbertodt/xswag-syntax-java rust
1566
+ aredotna/ervell typescript
1567
+ fxsjy/galaxy c
1568
+ ymichael/sessions go
1569
+ smartlogic/smartchat-android java
1570
+ bbondy/bloom-filter-js javascript
1571
+ paulboco/laravelerator php
1572
+ fprimex/zdesk python
1573
+ DigitalReflow/spina-projects ruby
1574
+ cmr/ioctl rust
1575
+ mihailik/TypeScript typescript
1576
+ leecrest/luv c
1577
+ wwitzel3/juju go
1578
+ rgupta1234/jboss-eap-quickstarts java
1579
+ bolinfest/line-ending-selector javascript
1580
+ mfairchild365/wubbles php
1581
+ praekelt/go-contacts-api python
1582
+ fsek/web ruby
1583
+ quvarxa/basic2d rust
1584
+ studieresan/overlord typescript
1585
+ kasper93/sanear c
1586
+ johnny-morrice/godelbrot go
1587
+ ralscha/eds-starter6-mongodb java
1588
+ klambycom/Skissa-och-gissa javascript
1589
+ dshafik/markua php
1590
+ MisanthropicBit/bibpy python
1591
+ ausaccessfed/saml-service ruby
1592
+ johannhof/markdown.rs rust
1593
+ dainst/idai-field-web typescript
1594
+ AMechler/AliPhysics c
1595
+ vektra/cypress go
1596
+ bitsquare/bitsquare java
1597
+ twisty/formsy-react-components javascript
1598
+ monooso/glossary.craft-plugin php
1599
+ thismachinechills/save_skype python
1600
+ AlexLittlejohn/ALCameraViewController ruby
1601
+ RustAudio/synth rust
1602
+ jupyter/jupyterlab typescript
1603
+ Icenowy/RUtil2 c
1604
+ sosedoff/envd go
1605
+ commonmark/commonmark-java java
1606
+ UTD-CSLLC/Door-Karma-Client javascript
1607
+ etsy/phan php
1608
+ lucianovdveekens/jiradoc python
1609
+ MLSDev/the_bullet-generator ruby
1610
+ endoli/disassemble.rs rust
1611
+ laodice/ionic-conference-app-session2 typescript
1612
+ Checkcoin/checkcoin c
1613
+ DarthSim/imgproxy go
1614
+ CompilerWorks/spliceengine java
1615
+ BBLN/data javascript
1616
+ jlorente/yii2-notification-module php
1617
+ ckan/ckanext-qa python
1618
+ stas/methane ruby
1619
+ febeling/edit-distance rust
1620
+ toladata/TolaProfile typescript
1621
+ simonaw/cutelyst c
1622
+ status-im/status-go go
1623
+ Genymobile/scrcpy java
1624
+ ImageMarkup/isic-archive javascript
1625
+ renothing/kanboard php
1626
+ hyunchel/redis-dump-load python
1627
+ ljfranklin/middleman-homepage ruby
1628
+ pduval/rustic_hal rust
1629
+ ngx-rocket/generator-ngx-rocket typescript
1630
+ lechkulina/RealmsOfSteel c
1631
+ alienth/go-fastly go
1632
+ m039/beacon-keeper java
1633
+ 3-Round-Stones/callimachus javascript
1634
+ Yubico/u2fval-client-php php
1635
+ ondergetekende/python-panavatar python
1636
+ boutil/roxml ruby
1637
+ nabijaczleweli/chattium-oxide-lib rust
1638
+ skatejs/skatejs typescript
1639
+ sferik/libxml-ruby c
1640
+ atlassian/git-lob go
1641
+ retest/recheck java
1642
+ GreenImp/rpg-dice-roller javascript
1643
+ marcaube/oauth2-server php
1644
+ tarpas/pytest-testmon python
1645
+ ubpb/metacrunch-mab2 ruby
1646
+ dtolnay/anyhow rust
1647
+ cloudevents/sdk-javascript typescript
1648
+ aclements/sv6 c
1649
+ vardius/go-api-boilerplate go
1650
+ AvaIre/AvaIre java
1651
+ davidrayoussef/full-screen-gif-slider javascript
1652
+ lossendae/Previously-on php
1653
+ yola/proxyprefix python
1654
+ alphagov/whitehall ruby
1655
+ dirvine/rust-utp rust
1656
+ tscholl2/smc typescript
1657
+ hxptls/P0000 c
1658
+ kusabashira/prod go
1659
+ telefonicaid/fiware-cosmos-platform java
1660
+ developer239/workbox-webpack-react javascript
1661
+ StealThisShow/StealThisTracker php
1662
+ ScatterHQ/eliot python
1663
+ 1337807/rubygems.org ruby
1664
+ naoty/table rust
1665
+ Sarah-Seo/Inpad typescript
1666
+ tizoc/chibi-shen c
1667
+ shiftky/go-tmsh go
1668
+ synchrotron-soleil-ica/continuous-materials java
1669
+ lm-tools/work-you-could-do javascript
1670
+ LidskaSila/Glow php
1671
+ NewKnowledge/punk python
1672
+ PagerDuty/lita-pagerduty ruby
1673
+ ms705/nom-sql rust
1674
+ daveross/catalogopolis-api typescript
1675
+ MTG/essentia c
1676
+ ninjasphere/go-ninja go
1677
+ mrts/vaadin-javaee-clinic-patient-queue-example java
1678
+ fma2/nyc-high-school-programs javascript
1679
+ nailsapp/module-comment php
1680
+ rdo-management/ironic-discoverd python
1681
+ daxadax/quotes ruby
1682
+ softprops/hyperlocal rust
1683
+ jacwright/typewriter typescript
1684
+ viccc/AHKNavigationController c
1685
+ AdamIsrael/juju go
1686
+ mcada/syndesis-qe java
1687
+ openspending/subsidystories.eu javascript
1688
+ joindin/joindin-web2 php
1689
+ igstan/redis-grep python
1690
+ dark-panda/ncsa-parser ruby
1691
+ glyn/jvmkill rust
1692
+ awayjs/awayjs-player typescript
1693
+ llvm-mirror/libclc c
1694
+ sttts/elastic-etcd go
1695
+ ChrisLMerrill/muse java
1696
+ jonsuh/hamburgers javascript
1697
+ soilby/queue-http-endpoint-bundle php
1698
+ opencord/voltha python
1699
+ deliveroo/ravelin-ruby ruby
1700
+ Rust-SDL2/rust-sdl2 rust
1701
+ pancho111203/JsonFormsEditor typescript
1702
+ xhochy/libfuzzymatch c
1703
+ jroimartin/syscallinfo go
1704
+ AxonFramework/AxonFramework java
1705
+ sanity-io/sanity javascript
1706
+ noopable/zf2 php
1707
+ xandr2/blynkapi python
1708
+ jphager2/pakyow ruby
1709
+ mvdnes/element76 rust
1710
+ BD2K-DDI/ddi-web-app typescript
1711
+ MarcoFalke/bitcoin c
1712
+ smkell/resolutionizerd go
1713
+ ryanbrainard/shoehorn java
1714
+ ceolter/ag-grid javascript
1715
+ delighted/delighted-php php
1716
+ exoanalytic/python-skyfield python
1717
+ ekylibre/ekylibre ruby
1718
+ hoodie/iso8601 rust
1719
+ flubstep/engvalues typescript
1720
+ mlatham/AFToolkit c
1721
+ kusabashira/catn go
1722
+ NCIP/national-biomedical-image-archive java
1723
+ bpsinc-native/src_third_party_trace-viewer javascript
1724
+ DOut4Harambe/starter-quotes php
1725
+ hobarrera/django-afip python
1726
+ bboe/sync_issues ruby
1727
+ justinas/gettext rust
1728
+ craft-ai/most-utils typescript
1729
+ gribozavr/swift c
1730
+ cnejame/ygor go
1731
+ reportportal/commons-dao java
1732
+ Tokimon/vanillajs-helpers javascript
1733
+ dwightwatson/autologin php
1734
+ Connexions/cnx-publishing python
1735
+ nycdot/transam_core ruby
1736
+ portier/portier-broker rust
1737
+ georgemarshall/DefinitelyTyped typescript
1738
+ raoulh/Enna-Media-Server c
1739
+ bobtfish/docker-consul-awsnycast go
1740
+ vsplf/vsplf-dynamic-i18n java
1741
+ ethan605/react-native-zero javascript
1742
+ letsdrink/ouzo php
1743
+ Charcoal-SE/SmokeDetector python
1744
+ jhilde/studentinsights ruby
1745
+ exonum/exonum rust
1746
+ gcriva/gcriva-frontend typescript
1747
+ gsamokovarov/chip8.c c
1748
+ brettchalupa/dat go
1749
+ ebi-uniprot/QuickGOBE java
1750
+ yamb/yamb javascript
1751
+ hypothesis/wordpress-theme-hypothesis php
1752
+ pfmoore/invoke python
1753
+ tutsplus/build-a-ruby-product-for-the-long-run ruby
1754
+ gnuvince/ppbert rust
1755
+ kactus-io/kactus typescript
1756
+ giginet/CCMessageWindow c
1757
+ mdlayher/goat go
1758
+ squix78/esp8266-oled-ssd1306-font-converter java
1759
+ navjobs/upload javascript
1760
+ foodsharing-dev/foodsharing-api php
1761
+ Calysto/metakernel python
1762
+ smtlaissezfaire/active_conductor ruby
1763
+ cwandrews/ed rust
1764
+ flybayer/next.js typescript
1765
+ AlexanderMazaletskiy/UICountingLabel c
1766
+ nlopes/slack go
1767
+ malikov/platform-android java
1768
+ marihachi/CrystalResonance javascript
1769
+ justcarakas/forkcms php
1770
+ CCI-MOC/GUI-Backend python
1771
+ marxarelli/vagrant ruby
1772
+ mattgreen/watchexec rust
1773
+ witheve/eve-starter typescript
1774
+ binlaten/framework c
1775
+ pointlander/peg go
1776
+ aureliano/achmed java
1777
+ taoger/highlight.js javascript
1778
+ dilawar/moodle php
1779
+ harvard-lil/h2o python
1780
+ jpmat296/homebrew-cask ruby
1781
+ uptech/alt rust
1782
+ vvfosprojects/sovvf typescript
1783
+ NLP/NLP c
1784
+ fimad/ggircd go
1785
+ ngageoint/mage-android java
1786
+ SomeoneWeird/new.nodejs.org javascript
1787
+ rinvex/cortex-foundation php
1788
+ binoculars/osf.io python
1789
+ theablefew/goodyear ruby
1790
+ felipesere/icepick rust
1791
+ AlexChesters/ukpd typescript
1792
+ Morphux/lib c
1793
+ rancherio/go-rancher go
1794
+ jswudi/alluxio java
1795
+ walmartlabs/circus-handlebars javascript
1796
+ bakape/r-a-d.io php
1797
+ kjordahl/swm python
1798
+ indeep-xyz/ruby-insensitive-search ruby
1799
+ eyolfson/eyl-shell rust
1800
+ jjhampton/angular2-tour-of-heroes typescript
1801
+ AperEntertainment/AperCommon c
1802
+ anacrolix/missinggo go
1803
+ folio-org/okapi java
1804
+ sbsmith86/neue javascript
1805
+ FlorentMetz/flotz php
1806
+ tomv564/LSP python
1807
+ icyflame/cutouts ruby
1808
+ graememcc/netStack rust
1809
+ scania/corporate-ui typescript
1810
+ embox/embox c
1811
+ giancosta86/caravel go
1812
+ Otanikotani/jacoco-parser java
1813
+ rakuten-frontend/rff-gulp javascript
1814
+ castlegateit/cgit-wp-breadcrumb-nav-menu php
1815
+ thomasballinger/tmuxp python
1816
+ cenit-io/cenit ruby
1817
+ opp11/calcr rust
1818
+ abraham/nutmeg-cli typescript
1819
+ ijacquez/libyaul c
1820
+ airbrake/gobrake go
1821
+ mikera/magic java
1822
+ matrix-org/matrix-react-sdk javascript
1823
+ shopixco/magento-clixgalore php
1824
+ philipdexter/vx python
1825
+ Eric-Guo/refinerycms ruby
1826
+ aepsil0n/rust rust
1827
+ azkurban/ng2 typescript
1828
+ chubbymaggie/asap c
1829
+ trasa/watchmud go
1830
+ Team08DatabaseProject/Healthy-Food-Ltd. java
1831
+ AbhilashSrivastava/haraka_sniffer javascript
1832
+ zburke/omnipay-bluepay php
1833
+ OnroerendErfgoed/crabpy python
1834
+ upinetree/nicorepo ruby
1835
+ matthiasbeyer/imag rust
1836
+ hslayers/hslayers-ng typescript
1837
+ yenWu/DDNS c
1838
+ kayex/chalmers-chop go
1839
+ testpress/android java
1840
+ unexpectedjs/unexpected javascript
1841
+ memborsky/irexinc.org php
1842
+ gviot/nadis python
1843
+ scotdalton/dayglo ruby
1844
+ antifuchs/chars rust
1845
+ xaverh/vscode-clang-format-provider typescript
1846
+ natsys/mariadb_10.2 c
1847
+ vanng822/aguin go
1848
+ davidmaignan/JDrive java
1849
+ lakrme/atom-levels javascript
1850
+ Osiruss/ForumTest php
1851
+ moreati/b-prefix-all-the-doctests python
1852
+ yonahforst/react-native-permissions ruby
1853
+ rust-lang/reference rust
1854
+ steveukx/git-js typescript
1855
+ achingupta/arm-trusted-firmware c
1856
+ tv42/becky go
1857
+ juve/corral java
1858
+ watilde/npm-report javascript
1859
+ fluxbb/commonmark php
1860
+ rudeb0t/DjangoAllowDeny python
1861
+ aliyun-beta/aliyun-openapi-ruby-sdk ruby
1862
+ hch12907/wiz rust
1863
+ sauli6692/ibc-server typescript
1864
+ rgde/lz4mt c
1865
+ divtxt/raft-consensus go
1866
+ yichen0831/SpaceMission java
1867
+ PonteIneptique/arethusa javascript
1868
+ Metrique/laravel-building php
1869
+ bodbdigr/restea python
1870
+ landrito/google-cloud-ruby ruby
1871
+ lise-henry/crowbook rust
1872
+ nodeswork/sbase typescript
1873
+ tdenniston/Halide c
1874
+ go-task/task go
1875
+ jakriz/derrick java
1876
+ TheBeastOfCaerbannog/kinospartak-bot javascript
1877
+ opdavies/sculpin php
1878
+ 7ws/django-emailer python
1879
+ wsmoak/chargify-examples ruby
1880
+ Fraser999/sodiumoxide rust
1881
+ akorchev/odata2openapi typescript
1882
+ nerdishbynature/octokit.swift c
1883
+ Chasego/cod go
1884
+ stefan-ka/dddsample-core java
1885
+ sharaal/dnode javascript
1886
+ remxcode/laravel-base php
1887
+ mandiant/ioc_writer python
1888
+ tumblr/ostrichpoll ruby
1889
+ squid-lang/squid rust
1890
+ JakeSidSmith/sensible-canvas-interface typescript
1891
+ jordemort/e17 c
1892
+ yumaikas/PISC-mirror go
1893
+ spark/photon-tinker-android java
1894
+ torbenbrodt/smarthome javascript
1895
+ BNETDocs/bnetdocs-web php
1896
+ cloudify-cosmo/tosca-vcloud-plugin python
1897
+ opsb/patchstream ruby
1898
+ jroesch/rust rust
1899
+ landonepps/vscode typescript
1900
+ dtzWill/ipcopter c
1901
+ CloudyKit/jet go
1902
+ gr8pefish/OpenGlider java
1903
+ controversial/controversial.io javascript
1904
+ guillaumebriday/laravel-blog php
1905
+ alisaifee/flask-limiter python
1906
+ tim-group/stackbuilder ruby
1907
+ rustoscript/french-press rust
1908
+ tbragaf/ng2-seed typescript
1909
+ rvandegrift/e c
1910
+ jonlawlor/matrixexp go
1911
+ liachmodded/Railcraft-API java
1912
+ sakmas/RetainerReport javascript
1913
+ nekodex/osu-web php
1914
+ xmunoz/sodapy python
1915
+ joshmcarthur/disclosure ruby
1916
+ 1tgr/rust-os rust
1917
+ aranja/tux typescript
1918
+ google/perfetto c
1919
+ Thomasdezeeuw/tools go
1920
+ project-ncl/dependency-analysis java
1921
+ adamsea/recipes-api javascript
1922
+ svpernova09/SvperCRM php
1923
+ mass-project/mass_api_client python
1924
+ kif-ev/oskiosk-server ruby
1925
+ KokaKiwi/rust rust
1926
+ scottohara/loot typescript
1927
+ klaaspieter/APIClient c
1928
+ kubernetes/apiextensions-apiserver go
1929
+ googleinterns/step57-2020 java
1930
+ InTeXration/InTeXration-Server javascript
1931
+ digitalkaoz/ivory-http-adapter php
1932
+ gsarma/ChannelWorm python
1933
+ dijonkitchen/shopping-api ruby
1934
+ japaric/rustc-builtins rust
1935
+ artsy/metaphysics typescript
1936
+ xistoso/CppSharp c
1937
+ dgageot/getme go
1938
+ ivargrimstad/mvc-samples java
1939
+ richarddewit/random-quotes javascript
1940
+ davidtsadler/ebay-sdk-trading php
1941
+ markbrough/exchangerates python
1942
+ degica/barcelona ruby
1943
+ rust-lang/libc rust
1944
+ Dia6lo/Mechanism typescript
1945
+ Geek-1001/Clue c
1946
+ royvandewater/go-to-hell go
1947
+ dimagi/commcare java
1948
+ theredcat/forge javascript
1949
+ kayladnls/doctrine-additions php
1950
+ TangledWeb/tangled.sqlalchemy python
1951
+ slawosz/rubinius ruby
1952
+ mneumann/lindenmayer-system rust
1953
+ Cinergix/rxdata typescript
1954
+ Aufree/phphub-ios c
1955
+ runner-mei/goal go
1956
+ jaxbot/android-preconditioning-leaf java
1957
+ airycanon/Ghost-Admin javascript
1958
+ lokothodida/php-simplequery php
1959
+ FlipperPA/wagtailpress python
1960
+ talk-to/NSData-TDTImageMIMEDetection ruby
1961
+ anastasia-tarasova/indy-sdk rust
1962
+ AyaMorisawa/node-powerful typescript
1963
+ ssp/Pester c
1964
+ maruel/dlibox go
1965
+ kuujo/copycat java
1966
+ ASzc/selfish-youtube javascript
1967
+ Hexanet/LogBundle php
1968
+ TangledWeb/tangled.website python
1969
+ SergXIIIth/vxod ruby
1970
+ Danite/NainEngine rust
1971
+ surveyjs/surveyjs typescript
1972
+ podio/podio-objc c
1973
+ simonjjones/atc go
1974
+ sveinnfannar/finagle java
1975
+ matrix-org/matrix-appservice-irc javascript
1976
+ Hng-X/linxer php
1977
+ sedders123/phial python
1978
+ 5xRuby/rubyconftw-cfp ruby
1979
+ daschl/grok rust
1980
+ RickCarlino/farmbot-web-app typescript
1981
+ qnu/qfs c
1982
+ anacrolix/dht go
1983
+ bearing/dosenet-apps java
1984
+ MaxWhere/electron javascript
1985
+ neonbug/meexo php
1986
+ JrGoodle/clowder python
1987
+ handcrafted/foundation ruby
1988
+ chriskrycho/lightning-rs rust
1989
+ marvinhagemeister/mobx-form-reactions typescript
1990
+ GaloisInc/halvm-ghc c
1991
+ localhots/satan go
1992
+ tcat-tamu/auth java
1993
+ jonkemp/wizard-mvc javascript
1994
+ libgraviton/graviton php
1995
+ kevgathuku/top40 python
1996
+ nyc-mud-turtles-2015/nghborly ruby
1997
+ dtolnay/quote rust
1998
+ briandk/transcriptase typescript
1999
+ adammurdoch/native-platform c
2000
+ thoas/picfit go
2001
+ joshsh/twitlogic java
2002
+ DTL-FAIRData/FAIRifier javascript
2003
+ Adldap2/Adldap2-laravel php
2004
+ erikrose/blessings python
2005
+ CrewLabs/tinplate ruby
2006
+ jmacdonald/luthor rust
2007
+ MadaraUchiha/se-chat-dark-theme-plus typescript
2008
+ 8l/scc c
2009
+ mmcdole/gofeed go
2010
+ adamski8/MyWeather java
2011
+ jerelmiller/redux-simple-auth javascript
2012
+ pfaocle/codeception-module-drupal-user-registry php
2013
+ yola/auth_tkt python
2014
+ mubi/user_preferences ruby
2015
+ j16r/rust rust
2016
+ AyaMorisawa/Disskey typescript
2017
+ waysome/libreset c
2018
+ pivotal-cf/cf-rabbitmq-release go
2019
+ SpineEventEngine/core-java java
2020
+ hanamura/gulp-minisite javascript
2021
+ nooku/nooku-platform php
2022
+ consbio/parserutils python
2023
+ akshaykarle/veewee ruby
2024
+ tov/libffi-rs rust
2025
+ frt/happyscheduler typescript
2026
+ jackromo/CNoodle c
2027
+ moovweb/tritium go
2028
+ facebook/litho java
2029
+ adube/ngeo javascript
2030
+ makeandship/acf-elasticsearch php
2031
+ archsh/tg2ext.express python
2032
+ brainopia/flow ruby
2033
+ gentoo90/winreg-rs rust
2034
+ virtuoushub/game-off-2016 typescript
2035
+ PaystackHQ/paystack-ios c
2036
+ jimmidyson/minishift go
2037
+ JRebirth/JRebirth java
2038
+ madrobby/scripty2 javascript
2039
+ njam/denkmal.org php
2040
+ MichaelYusko/Bot-Chucky python
2041
+ jakerenzella/doubtfire-api ruby
2042
+ sakeven/rust-rosetta rust
2043
+ arusakov/DefinitelyTyped typescript
2044
+ mtulio/kb c
2045
+ cybozu-go/log go
2046
+ rebasar/lunchy java
2047
+ cedaro/cedaro-wp-theme-config javascript
2048
+ mattsah/bustle php
2049
+ ryanmcdermott/birdseed python
2050
+ arkency/rails_event_store ruby
2051
+ jedisct1/sodiumoxide rust
2052
+ gluons/vue-thailand-address typescript
2053
+ APCVSRepo/sdl_ios c
2054
+ xqin/miniflux go
2055
+ Brokkonaut/CubeQuest java
2056
+ Turistforeningen/Hytteadmin javascript
2057
+ activecollab/databasestructure php
2058
+ mociepka/saleor python
2059
+ turboladen/playful ruby
2060
+ maghoff/bart rust
2061
+ reactivestack/cookies typescript
2062
+ e-mission/cordova-server-sync c
2063
+ pivotal-cf-experimental/bosh-bootloader go
2064
+ CapOM/ChromiumGStreamerBackend java
2065
+ DoctorMcKay/node-steam-tradeoffer-manager javascript
2066
+ ampproject/amp-toolbox-php php
2067
+ GallopLabs/facebook-ads-api python
2068
+ et/clamshell ruby
2069
+ szeged/servo rust
2070
+ Romakita/ts-express-decorators typescript
2071
+ guilherme-pg/lyra2 c
2072
+ exercism/cli go
2073
+ CDRussell/CasterRxJava java
2074
+ ffont/freesound-explorer javascript
2075
+ yapici/Inventory-Management-System php
2076
+ rail/releasetasks python
2077
+ dhemery/latex-markdown ruby
2078
+ aldanor/typeinfo rust
2079
+ rootulp/exercism typescript
2080
+ cmr/seL4 c
2081
+ tardisx/discord-auto-upload go
2082
+ MacroData/skyprint java
2083
+ AyaNakazawa/business_card_bank javascript
2084
+ kielabokkie/dotenv-diff php
2085
+ sebdah/yayson python
2086
+ WikiEducationFoundation/WikiEduDashboard ruby
2087
+ nbigaouette/gitlab-api-rs rust
2088
+ jupl/astraea typescript
2089
+ mfrey/RIOT c
2090
+ google/wuffs go
2091
+ jenkinsci/codedx-plugin java
2092
+ ScottMaclure/scott-cv javascript
2093
+ omise/omise-magento php
2094
+ serge-sans-paille/gast python
2095
+ mnipper/rails_survey ruby
2096
+ tohou/diesel rust
2097
+ joelgeorgev/file-hash-verifier typescript
2098
+ chaitanyav/cprograms c
2099
+ pivotal-cf/cred-alert go
2100
+ Zaggy1024/MinecraftForge java
2101
+ nickmccurdy/purespec javascript
2102
+ bryanlatten/docker-php php
2103
+ adlibre/django-bcp python
2104
+ beni55/falcor-1 ruby
2105
+ kjgorman/basiccms.rs rust
2106
+ jiahaog/Nativefier typescript
2107
+ joeljk13/Timer c
2108
+ drewsetski/koding go
2109
+ TeamWertarbyte/craften-launcher java
2110
+ pluggerjs/plugger javascript
2111
+ GeniusTS/preferences php
2112
+ ayushgoel/mstranslator python
2113
+ chef/em-winrm ruby
2114
+ samdoshi/portmidi-rs rust
2115
+ kiswa/TaskBoard typescript
2116
+ fujunwei/chromium-crosswalk c
2117
+ UserStack/ustackweb go
2118
+ jitsi/jitsi java
2119
+ HermanFassett/project-osiris-website javascript
2120
+ symfony/security-core php
2121
+ gilesbrown/python-icapservice python
2122
+ rubyforgood/diaper ruby
2123
+ kwantam/rust rust
2124
+ pd4d10/intelli-octo typescript
2125
+ KristFoundation/Programs c
2126
+ jrupac/goliath go
2127
+ quarkusio/quarkus java
2128
+ gaearon/redux javascript
2129
+ DarvinStudio/DarvinAdminBundle php
2130
+ nigma/dj-cmd python
2131
+ gds-attic/contact-o-tron ruby
2132
+ rsaarelm/magog rust
2133
+ ipatalas/vscode-postfix-ts typescript
2134
+ jmurzy/nodegit c
2135
+ pkg/browser go
2136
+ filestack/filestack-java java
2137
+ spherelot/teamboard-api javascript
2138
+ souldigital/silverstripe-userforms php
2139
+ srittau/rouver python
2140
+ theodi/panopticon ruby
2141
+ Wallacoloo/serde_osc rust
2142
+ Goyatuzo/LurkerBot typescript
2143
+ tbporter/http-server c
2144
+ datawire/telepresence go
2145
+ IchorPowered/Latch java
2146
+ itsananderson/burden javascript
2147
+ occitech/Occitech_ShopyMind php
2148
+ VirgilSecurity/virgil-sdk-python python
2149
+ Arie/serveme ruby
2150
+ aepsil0n/graphics rust
2151
+ MikeBull94/aurelia-hacker-news typescript
2152
+ haxpor/playbasis-ios c
2153
+ vrischmann/rdbtools go
2154
+ scenarioo/scenarioo-selenium-demo java
2155
+ mafintosh/protocol-buffers-schema javascript
2156
+ BKWLD/upchuck php
2157
+ verilylifesciences/analysis-py-utils python
2158
+ fakefs/fakefs ruby
2159
+ CensoredUsername/dynasm-rs rust
2160
+ WorldBrain/WebMemex typescript
2161
+ altMITgcm/MITgcm66h c
2162
+ Logiraptor/oak go
2163
+ pholser/junit-quickcheck java
2164
+ UKHomeOffice/passports-prototype javascript
2165
+ Simovative/zeus php
2166
+ compunova/kozinaki python
2167
+ t-morgan/sequel ruby
2168
+ ghotiphud/rust-rosetta rust
2169
+ eskatos/gradle-command-action typescript
2170
+ yitian134/chromium c
2171
+ materials-commons/materials go
2172
+ theworldbright/SoundLocker java
2173
+ otacke/h5p-agamotto javascript
2174
+ frqnck/apix php
2175
+ wangjohn/zinc_cli python
2176
+ thekompanee/fuubar ruby
2177
+ steveklabnik/rust_example rust
2178
+ PioneerCode/pioneer-tree typescript
2179
+ Jtalk/kopete-fork-xep0136 c
2180
+ keybase/client go
2181
+ jimmyli97/mathosphere java
2182
+ ohmanger/userscripts javascript
2183
+ MTon/api php
2184
+ SCUEvals/scuevals-api python
2185
+ alphagov/manuals-publisher ruby
2186
+ yasuyuky/ghteam-auth rust
2187
+ ngako/angular2-poc typescript
2188
+ daukantas/octokit.objc c
2189
+ rafaeljusto/gddoexp go
2190
+ jpaoletti/java-presentation-manager java
2191
+ yangmillstheory/chunkify javascript
2192
+ digitoimistodude/air php
2193
+ ifduyue/urlfetch python
2194
+ danielwestendorf/blow_pipe ruby
2195
+ sgrif/diesel rust
2196
+ algorithm-ninja/task-wizard typescript
2197
+ Vector35/binaryninja-api c
2198
+ mscoutermarsh/exercism_coveralls go
2199
+ aislab-hevs/magpie java
2200
+ PrasannaVenkadesh/portia javascript
2201
+ hfcorriez/pagon php
2202
+ cychiang/mafan python
2203
+ Promoboxx/cookbooks_public ruby
2204
+ nodakai/rust-static_assert_macro rust
2205
+ Clever/node-process-metrics typescript
2206
+ rbld/rebuild c
2207
+ matt-royal/cf-acceptance-tests go
2208
+ jerome79/OG-Platform java
2209
+ codarchlab/idai-field-client javascript
2210
+ at15/MissAtomicBomb php
2211
+ mcmtroffaes/pathlib2 python
2212
+ jawj/passenger ruby
2213
+ olson-sean-k/plexus rust
2214
+ ospatil/generator-node-typescript typescript
2215
+ nickelsberry/AXStretchableHeaderTabViewController c
2216
+ lxc/lxd go
2217
+ nallar/TickThreading java
2218
+ hjtoday/CBoard javascript
2219
+ DanTheDJ/multitenant php
2220
+ tilezen/scoville python
2221
+ BBC-News/alephant-renderer ruby
2222
+ stallmanifold/rust-multiboot2 rust
2223
+ WeAreWizards/crumpets typescript
2224
+ Raizlabs/BonMot c
2225
+ facesea/banshee go
2226
+ jpodeszwik/mifos java
2227
+ firebug/tracing-console javascript
2228
+ highway-accident/tracker php
2229
+ pczerkas/captainhook python
2230
+ mirego/bourgeois ruby
2231
+ rprichard/rust rust
2232
+ artfuldev/RIoT typescript
2233
+ laarmen/lua_debug c
2234
+ ranjithamca/gru go
2235
+ ProxyPrint/proxyprint-kitchen java
2236
+ yajinni/WoWAnalyzer javascript
2237
+ nimbusoftltd/parrot php
2238
+ benedictpaten/cactus python
2239
+ kolorahl/warden-token ruby
2240
+ ttokutake/kic rust
2241
+ uwdata/vega-lite typescript
2242
+ hgl888/chromium-crosswalk-efl c
2243
+ pierreozoux/guides go
2244
+ vespa-engine/vespa java
2245
+ umasudhan/weather javascript
2246
+ navarr/advent-of-code php
2247
+ caktus/django-pagelets python
2248
+ jnunemaker/httparty ruby
2249
+ gifnksm/rust rust
2250
+ joelgeorgev/react-checkbox-tree typescript
2251
+ NiVZ78/concentricity c
2252
+ HeiaHeia/trello-bot go
2253
+ epimorphics/dclib java
2254
+ metidia/waterline javascript
2255
+ denkmal/denkmal.org php
2256
+ suminb/urwid-stackedwidget python
2257
+ jamesotron/MrDarcy ruby
2258
+ tilpner/ilc rust
2259
+ jbrowneuk/jblog typescript
2260
+ ring-lang/ring c
2261
+ go-interpreter/wagon go
2262
+ conveyal/gtfs-data-manager java
2263
+ rawrsome/firebase-simple-login javascript
2264
+ mitchfizz05/Sphinx php
2265
+ alphagov/stagecraft python
2266
+ renewablefunding/huddle ruby
2267
+ gustavla/numeric rust
2268
+ inad9300/Soil typescript
2269
+ jvns/kernel-module-fun c
2270
+ cjcjameson/fly go
2271
+ KILFaT/BudgetKeeper java
2272
+ MyEtherWallet/MyEtherWallet javascript
2273
+ rocketeers/rocketeer php
2274
+ Connexions/cnx-authoring python
2275
+ clhynfield/vagrant-ansible-osx ruby
2276
+ way-cooler/way-cooler rust
2277
+ disjukr/jews typescript
2278
+ Zlacki/slackboat c
2279
+ Cepave/open-falcon-backend go
2280
+ athy/fape java
2281
+ maxdome/maxdome-node javascript
2282
+ dimitriacosta/html php
2283
+ agoragames/py-eventsocket python
2284
+ ilackarms/manageiq ruby
2285
+ olson-sean-k/bismuth rust
2286
+ Alberthaff/ngx-papaparse typescript
2287
+ TolikH/ofp c
2288
+ mistifyio/mistify-operator-admin go
2289
+ ksoichiro/spring-boot-practice java
2290
+ unkhz/almost-static-site javascript
2291
+ moazam1/telegram-bot-sdk php
2292
+ evoja/docker-Github-Gitlab-Auto-Deploy python
2293
+ joeosburn/cannon ruby
2294
+ DimaKudosh/difflib rust
2295
+ Hersir88/Babylon.js typescript
2296
+ GNOME/json-glib c
2297
+ oakmound/oak go
2298
+ damianham/react-native-audio-kit java
2299
+ jonkemp/inline-css javascript
2300
+ r3oath/hive php
2301
+ incuna/feincms-extensions python
2302
+ k1w1/rendered-multi-select ruby
2303
+ bluss/quickcheck rust
2304
+ oster/mute typescript
2305
+ JuudeDemos/fb-adb c
2306
+ pivotal-cf-experimental/destiny go
2307
+ electrum/presto-hive-apache java
2308
+ derektliu/Picky-Notes javascript
2309
+ FriendsOfCake/CakePdf php
2310
+ zmbq/djqgrid python
2311
+ djsegal/julia_observer ruby
2312
+ Techern/Netherrack rust
2313
+ SevereOverfl0w/Unicorn-UI-Kit typescript
2314
+ libfirm/libfirm c
2315
+ danstis/Plex-Sync go
2316
+ DevOpsDistilled/OpERP java
2317
+ getninjas/gaiden javascript
2318
+ cs278/bank-modulus php
2319
+ kevinconway/rpmvenv python
2320
+ cyber-dojo/web ruby
2321
+ gadomski/sdc-rs rust
2322
+ ABAPlan/abaplan-core typescript
2323
+ learnclang/1-helloworld c
2324
+ Roadagain/Chess go
2325
+ Axway/ats-framework java
2326
+ wooken/mptlog javascript
2327
+ hannesvdvreken/guzzle-debugbar php
2328
+ maxzheng/workspace-tools python
2329
+ dplarson/gitlabhq ruby
2330
+ emk/rust-cld2 rust
2331
+ crossroads-education/eta-cli typescript
2332
+ Phyllostachys/junkcode c
2333
+ kl4w/terraform go
2334
+ cs3250-team6/msubanner java
2335
+ darthjee/frog javascript
2336
+ mkusher/padawan.php php
2337
+ thsnr/gygax python
2338
+ gavinlaking/troo ruby
2339
+ klutzy/suruga rust
2340
+ FarmBot/farmbot-web-app typescript
2341
+ ZoranPandovski/al-go-rithms c
2342
+ pivotal-cf-experimental/vizzini go
2343
+ bcgit/bc-java java
2344
+ vikpe/react-webpack-typescript-starter javascript
2345
+ Hackathonners/swap php
2346
+ theislab/dca python
2347
+ hopshadoop/chef-glassfish ruby
2348
+ nicokoch/gl-rs rust
2349
+ artsy/reaction typescript
2350
+ en90/pkg c
2351
+ kingsamchen/Eureka go
2352
+ pagarme/pagarme-java java
2353
+ razh/osc-dev javascript
2354
+ nicklaw5/twitch-api-php php
2355
+ iamwucheng/xml_models2 python
2356
+ bobbytables/gemfiler ruby
2357
+ klingtnet/rosc rust
2358
+ jvilk/doppio-demo typescript
2359
+ apple/swift-llvm c
2360
+ weaveworks/flux go
2361
+ gradle/gradle java
2362
+ gaearon/normalizr javascript
2363
+ fniephaus/SimpleDropboxUploader php
2364
+ divio/django-cas python
2365
+ isadaqah/irc-hipchat-integration ruby
2366
+ mvdnes/rboy rust
2367
+ yinxin630/fiora typescript
2368
+ tiennou/objective-git c
2369
+ li-ang/influxdb go
2370
+ gogradle/gogradle java
2371
+ Sleavely/OTWorlds javascript
2372
+ hugomelo/ralsp php
2373
+ johnpaulett/txHL7 python
2374
+ amateurhuman/active_esp ruby
2375
+ jcolag/CommonCalendar rust
2376
+ shamblesides/rpnow typescript
2377
+ happyponyland/smallrl c
2378
+ krasun/ProjectEulerSolutions go
2379
+ janosgyerik/java-tools java
2380
+ jeremija/peer-calls javascript
2381
+ srayner/zend-db php
2382
+ twig/django-taggit python
2383
+ cegeka/puppet-rabbitmq ruby
2384
+ tdaede/mpv-rice rust
2385
+ mauve/vscode-terraform typescript
2386
+ AltSysrq/tgl c
2387
+ rafaeljribeiro/geocoder go
2388
+ pushtechnology/diffusion-transform java
2389
+ simplyianm/classtime javascript
2390
+ NZRS/dnscheck php
2391
+ gasman/Willow python
2392
+ SpringMT/worker_scoreboard ruby
2393
+ iKevinY/ghoti.rs rust
2394
+ imribarr-compit/ng2-bootstrap typescript
2395
+ blinkboxbooks/blinkbox-network.objc c
2396
+ antontsv/twilio go
2397
+ Bananeweizen/cgeo java
2398
+ zillding/hangouts javascript
2399
+ ashfordl/blog php
2400
+ smarkets/statprof python
2401
+ ArchimedesPi/printit ruby
2402
+ solson/rin rust
2403
+ Dynalon/redux-pattern-with-rx typescript
2404
+ spewspew/TAOCP c
2405
+ messagebird/go-rest-api go
2406
+ kiorpesc/CS1622-Project3 java
2407
+ ExchangeCore/Concrete5-CKEditor javascript
2408
+ persand/sfdaycgn2011 php
2409
+ 360youlun/cmsplugin-bootstrap-carousel python
2410
+ NUBIC/dagnabit ruby
2411
+ andars/rust-calculator rust
2412
+ to2mbn/skinview3d typescript
2413
+ anton-simakov/ASFeedly c
2414
+ holygeek/translator go
2415
+ itszootime/geojson-java java
2416
+ google/site-kit-wp javascript
2417
+ osuripple/ripple php
2418
+ ceball/param python
2419
+ biow0lf/evemonk ruby
2420
+ erik/sketches rust
2421
+ concord-consortium/building-models typescript
2422
+ blueseaguo/ios-library c
2423
+ arapov/pile go
2424
+ ratan12/Atarashii java
2425
+ martindale/melody javascript
2426
+ ffsantos92/bens-penhorados php
2427
+ associazionepoltronieri/blender-ap python
2428
+ paulmolin42/mjmr ruby
2429
+ mario-kr/imag rust
2430
+ Rebilly/ReDoc typescript
2431
+ cinnamoncoin/Feathercoin c
2432
+ sosedoff/howdy go
2433
+ SteveWinfield/IDK-Server-Java java
2434
+ ardeshirj/atom javascript
2435
+ palmtreephp/canonical-url-bundle php
2436
+ wikilinks/sift python
2437
+ rwehresmann/stack_helper ruby
2438
+ aochagavia/Serve rust
2439
+ atomiks/tippyjs typescript
2440
+ candy7393/VTK c
2441
+ scipipe/scipipe go
2442
+ Lydwen/CentralTrafficLightManagement-SmartCity java
2443
+ tejasbubane/xecmascript javascript
2444
+ richardhinkamp/giveandgo-website php
2445
+ DesertBot/DesertBot python
2446
+ benjaminhyw/rails-online-shop ruby
2447
+ sfackler/rust-postgres rust
2448
+ jonaskello/tslint-immutable typescript
2449
+ appsembler/edx-app-ios c
2450
+ jmalonzo/project-euler-solutions go
2451
+ rhuss/sundrio java
2452
+ lucy-marko/centrepoint javascript
2453
+ Lab2Comp4711/comp4711-lab02 php
2454
+ 4degrees/segue python
2455
+ AnimaGUS-minerva/www ruby
2456
+ Shraddha512/servo rust
2457
+ sobstel/golazon typescript
2458
+ Furkanzmc/StateManager c
2459
+ ava-labs/avalanchego go
2460
+ RBMHTechnology/apidoc-server java
2461
+ pshendry/DevQuest javascript
2462
+ aaaaadrien/marjo21 php
2463
+ holdenweb/nbtools python
2464
+ nhocki/version_gemfile ruby
2465
+ leonardinius/rust-guide rust
2466
+ wishtack/ng-steroids typescript
2467
+ charsyam/hiredis c
2468
+ benjojo/aprs.go go
2469
+ JEEventStore/JEECQRS java
2470
+ Fluidbyte/ColtJS javascript
2471
+ donatj/CorpusPHP php
2472
+ openhealthcare/opal-referral python
2473
+ listia/con_air ruby
2474
+ Drakulix/zwreec rust
2475
+ aaldaber/owid-grapher typescript
2476
+ malensek/3RVX c
2477
+ hashicorp/terraform go
2478
+ tbrooks8/Precipice java
2479
+ digabi/math-editor javascript
2480
+ meanbee/articles-to-podcast php
2481
+ BansheeMediaPlayer/bockbuild python
2482
+ zhoutong/interapp ruby
2483
+ mcpherrinm/baudot rust
2484
+ kesarion/angular2-air-datepicker typescript
2485
+ fsavje/scclust c
2486
+ bahlo/godisc go
2487
+ vivo-project/VIVO java
2488
+ visionmedia/node-progress javascript
2489
+ alberanid/bookmarks php
2490
+ elacuesta/scrapy python
2491
+ davidleach/onebody ruby
2492
+ bvinc83/lz4-rs rust
2493
+ CAAL/CAAL typescript
2494
+ lees0414/EUproject c
2495
+ jpfuentes2/go-env go
2496
+ pmcs/nassau java
2497
+ jsonmvc/jsonmvc javascript
2498
+ pH7Software/pH7-Social-Dating-CMS php
2499
+ mbr/flask-appconfig python
2500
+ tomekw/yaml_converters ruby
2501
+ 0xd4d/iced rust
2502
+ fyoudine/three.js typescript
2503
+ whoshuu/cpr c
2504
+ opentable/sous go
2505
+ johanbrook/watchme java
2506
+ msanatan/GitHubProjects javascript
2507
+ sakara/PazWork php
2508
+ ninjawil/weather-station python
2509
+ taskrabbit/makara ruby
2510
+ Hoverbear/rust-rosetta rust
2511
+ Jameskmonger/isaac-crypto typescript
2512
+ metora/MesaGLSLCompiler c
2513
+ carlosbrando/lunchy go
2514
+ jedrz/slisp java
2515
+ mthmulders/lin2go javascript
2516
+ futurable/backend php
2517
+ sunlightlabs/thezombies python
2518
+ kaosf/apns-s3 ruby
2519
+ mehcode/config-rs rust
2520
+ DorianGrey/ng2-webpack-template typescript
2521
+ google/skia c
2522
+ cpmech/gosl go
2523
+ monkey2000/Wikidata-Toolkit java
2524
+ mozilla/openbadges-discovery javascript
2525
+ Palethorn/Yeah php
2526
+ PanDAWMS/panda-bigmon-atlas python
2527
+ nguyenquangminh0711/ruby-sensor ruby
2528
+ petertseng/exercism-rust rust
2529
+ UITools/saleor typescript
2530
+ danluu/setjmp-longjmp-ucontext-snippets c
2531
+ jroimartin/tgbot go
2532
+ GoogleCloudPlatform/appengine-gcs-client java
2533
+ taylorzane/noflo-ui javascript
2534
+ FreshRSS/update.freshrss.org php
2535
+ varunarya10/oslo.i18n python
2536
+ luwei2012/BlurryModalSegue ruby
2537
+ theemathas/binary_turk rust
2538
+ syuilo/Misskey typescript
2539
+ delwink/libpatts c
2540
+ cixtor/slackapi go
2541
+ njmube/OpERP java
2542
+ antoinechalifour/Reddix javascript
2543
+ jonnybarnes/jonnybarnes.uk php
2544
+ jefrailey/basic-scraper python
2545
+ ywzw2013/CKRefreshControl ruby
2546
+ Razaekel/noise-rs rust
2547
+ artfuldev/tictactoe-ai typescript
2548
+ cinode/cpptestapp c
2549
+ shurcooL/go go
2550
+ SEARCH-NCJIS/nibrs java
2551
+ disquisition/serve javascript
2552
+ laravel-zero/framework php
2553
+ udibr/fuel python
2554
+ hightower/cash_flow_analysis ruby
2555
+ kinghajj/minimax-rs rust
2556
+ ryohey/signal typescript
2557
+ vortexntnu/rov-control c
2558
+ concourse/concourse go
2559
+ martijn-heil/KingdomEssentials java
2560
+ ryym/babel-rewire-wrapper javascript
2561
+ EugenZi/oro-platform-app php
2562
+ haridsv/fabric python
2563
+ guerrero/homebrew-cask ruby
2564
+ alexwlchan/safari.rs rust
2565
+ online-poker/poker-html-client typescript
2566
+ giuliopaci/acopost c
2567
+ abustany/go go
2568
+ yuvraaz/android-push-notification java
2569
+ BAJ-/robot-breakout javascript
2570
+ sebastiaanluca/laravel-modules php
2571
+ gadventures/gapipy python
2572
+ bimmlerd/homebrew-versions ruby
2573
+ imazen/imageflow rust
2574
+ nmarsden/make-em-green typescript
2575
+ hlnd/nrf51-simple-radio c
2576
+ npe9/noahevans-go9 go
2577
+ sebhoss/annotated-contracts java
2578
+ bustlelabs/content-kit-editor javascript
2579
+ jeroendelau/slim-basic-auth php
2580
+ sk-/python2.7-type-annotator python
2581
+ unboxed/hrcomply-demo ruby
2582
+ rhysd/git-brws rust
2583
+ emc-mongoose/console typescript
2584
+ prajnashi/ffmpeg c
2585
+ callpraths/gorobdd go
2586
+ detectiveframework/detective java
2587
+ znetstar/broadway javascript
2588
+ plattinum09/CMS_SENTRY php
2589
+ mythmon/kitsune python
2590
+ zwaldowski/BlocksKit ruby
2591
+ sevagh/pqrs rust
2592
+ wikiwi/react-jss-theme typescript
2593
+ fgouget/spice c
2594
+ ggoblin/goblin go
2595
+ PDXFinder/pdxfinder java
2596
+ freezy-sk/bootlint javascript
2597
+ google/site-kit-wp php
2598
+ j4mie/django-activelink python
2599
+ bryckbost/memdash ruby
2600
+ willsalz/actors rust
2601
+ chipster/chipster-web typescript
2602
+ kopasiak/gt c
2603
+ cloudfoundry-incubator/cf-test-helpers go
2604
+ bf8086/alluxio java
2605
+ zarazi/movies-listie javascript
2606
+ bauhausphp/package-container php
2607
+ jwg4/flask-autodoc python
2608
+ mygulamali/compare-sunrise-gems ruby
2609
+ rootulp/exercism rust
2610
+ CodeForCharlotte/cmpd-holiday-gift-backend typescript
2611
+ cs2103aug2014-w10-1c/main c
2612
+ RobinUS2/xyzfs go
2613
+ MovingBlocks/Terasology java
2614
+ rhysd/node-client javascript
2615
+ leocavalcante/siler php
2616
+ EmadMokhtar/halaqat python
2617
+ Erol/specter ruby
2618
+ muktakosh/unicorn rust
2619
+ FoalTS/foal typescript
2620
+ zhangzhehust/htcondor c
2621
+ robdimsdale/wl go
2622
+ stickfigure/gstrap-gae java
2623
+ camayak/contentapi-medium-node javascript
2624
+ timegridio/timegrid php
2625
+ EDUlib/edx-platform python
2626
+ bengler/tootsie ruby
2627
+ phaazon/ion rust
2628
+ MyMICDS/MyMICDS-v2-Angular typescript
2629
+ JohnReid/myrrh c
2630
+ DanShu93/trainspotter go
2631
+ HubSpot/jackson-datatype-protobuf java
2632
+ pedro-lucas/node-pdfbox javascript
2633
+ dannyvankooten/vat.php php
2634
+ Graylog2/graylog-ansible-role python
2635
+ peter-murach/tty ruby
2636
+ erickt/rust rust
2637
+ pratheekhegde/a2-redux typescript
2638
+ CodethinkLabs/ofc c
2639
+ peteretelej/saf go
2640
+ GerritCodeReview/gerrit java
2641
+ ise-ethereum/on-chain-chess javascript
2642
+ wpsvse/wpackagist php
2643
+ armab/st2contrib python
2644
+ ReadyResponder/ReadyResponder ruby
2645
+ mayah/rust-puyoai rust
2646
+ Urigo/angular-meteor typescript
2647
+ mnaza/themis c
2648
+ cloudfoundry-incubator/guardian-release go
2649
+ weisJ/darklaf java
2650
+ pirelenito/unbubble javascript
2651
+ nailsapp/module-email php
2652
+ KrzysztofSendor/dactyl python
2653
+ MortadaAK/ProMotion ruby
2654
+ gluon-lang/try_gluon rust
2655
+ srackham/rimu typescript
2656
+ hujiajie/pa-chromium c
2657
+ tedsuo/ifrit go
2658
+ scijava/scijava-jupyter-kernel java
2659
+ gish/friskis-slack-booking javascript
2660
+ bound1ess/adviser php
2661
+ nurav/balrog python
2662
+ nibua-r/testext ruby
2663
+ PhilipDaniels/qork rust
2664
+ Jigsaw-Code/outline-server typescript
2665
+ pavelkryukov/putty-aes-ni c
2666
+ pekim/gotk3 go
2667
+ ferreusveritas/Growing-Trees java
2668
+ folio-org/stripes-core javascript
2669
+ xiidea/EasyAuditBundle php
2670
+ Pierre-Sassoulas/django-survey python
2671
+ thii/homebrew-cask ruby
2672
+ Acizza/anitrack rust
2673
+ bluebirrrrd/nau-timetable typescript
2674
+ ecalvovi/AliRoot c
2675
+ mortdeus/goblin go
2676
+ liujed/polyglot-eclipse java
2677
+ facebook/draft-js javascript
2678
+ Luceos/core php
2679
+ microsoft/dpu-utils python
2680
+ eonum/drg-search ruby
2681
+ nvzqz/static-assertions-rs rust
2682
+ Ecafracs/flatthirteen typescript
2683
+ ppy/osu-framework c
2684
+ Urethramancer/lbapi go
2685
+ davidsusu/tree-printer java
2686
+ nissoh/core javascript
2687
+ billmn/gorilla php
2688
+ PersonalGenomesOrg/open-humans python
2689
+ ledermann/docker-rails ruby
2690
+ xiph/rav1e rust
2691
+ gamliela/starter-react-mobx-css-modules typescript
2692
+ skarnet/s6-linux-init c
2693
+ qasim/what-class-is-this go
2694
+ aNNiMON/JECP java
2695
+ ONSdigital/florence javascript
2696
+ alfaproject/omnipay-skrill php
2697
+ vayan/external-video python
2698
+ rehanone/puppet-git ruby
2699
+ tempbottle/rust-peg rust
2700
+ nekodex/osu-web typescript
2701
+ crontab/libobjc2 c
2702
+ zombiezen/go-log go
2703
+ Suseika/collections-utils java
2704
+ MichaelKohler/mozilla-watcher javascript
2705
+ dafik/CodeGen php
2706
+ simonjbeaumont/xcp-rrdd python
2707
+ braintree/braintree-web-drop-in ruby
2708
+ GuzTech/tray_rust rust
2709
+ kawamon/hue typescript
2710
+ jpoirier/picoc c
2711
+ cloudfoundry-incubator/nsync go
2712
+ robertoschwald/cas java
2713
+ formidable-coffee/masterfully javascript
2714
+ dweidner/laravel-goutte php
2715
+ lozadaOmr/ansible-admin python
2716
+ pinzolo/redmine_persist_wfmt ruby
2717
+ adeschamps/lcm rust
2718
+ sheldarr/Votenger typescript
2719
+ ryepdx/keyphrase c
2720
+ monzo/typhon go
2721
+ aleph-zero/presto java
2722
+ npmcomponent/ramitos-midway javascript
2723
+ nordsoftware/lumen-core php
2724
+ ulikoehler/UliEngineering python
2725
+ dtan4/organicat ruby
2726
+ Zamicol/Challenge rust
2727
+ Flatline4/Flatline4 typescript
2728
+ echonest/libechonest c
2729
+ PufferPanel/PufferPanel go
2730
+ microprofile/microprofile-conference java
2731
+ jamen/craze javascript
2732
+ facile-it/paraunit php
2733
+ kxxoling/fabric python
2734
+ zurb/inky-rb ruby
2735
+ musoke/inspirer rust
2736
+ dragma/styled-bootstrap-grid typescript
2737
+ AAChartModel/AAChartKit c
2738
+ rancher/rancher go
2739
+ InnovateUKGitHub/innovation-funding-service java
2740
+ etopian/codebox-package-menubar javascript
2741
+ Radvance/Radvance php
2742
+ EmilStenstrom/nephele python
2743
+ sandro/ephemeral_response ruby
2744
+ spacejam/sled rust
2745
+ molstar/molstar typescript
2746
+ qtmediahub/sasquatch c
2747
+ firestudios/qor-example go
2748
+ ryanbrainard/richsobjects java
2749
+ SentinelsOfMagic/SentinelsOfMagic javascript
2750
+ unl/UNL_UCBCN_System php
2751
+ chingc/DJRivals python
2752
+ joeyates/ruby-sun-times ruby
2753
+ terminalcloud/libnetfilter_queue rust
2754
+ larsvanbraam/vue-transition-component typescript
2755
+ isbadawi/badavi c
2756
+ ianopolous/go-ipfs go
2757
+ scottfrederick/spring-boot java
2758
+ burningtomatoes/Bitsmashers javascript
2759
+ dkgndec/DrupalConsole php
2760
+ docsbox/docsbox python
2761
+ Teino1978-Corp/Teino1978-Corp-kaminari ruby
2762
+ fanderzon/rocket-api rust
2763
+ rtsjs/rts typescript
2764
+ darkbuck/Halide c
2765
+ go-gl/gl go
2766
+ gabrielavara/music-player java
2767
+ weepower/wee-core javascript
2768
+ dxw/php-missing php
2769
+ uva-financial-engineering/cifer-tournament python
2770
+ moneyadviceservice/mas-feedback ruby
2771
+ crumblingstatue/rust-libnotify-sys rust
2772
+ nrlquaker/nfov typescript
2773
+ qsctr/vex-4194b-2016 c
2774
+ spacedock-io/registry go
2775
+ Steveice10/MCProtocolLib java
2776
+ CVBDL/EagleEye-App javascript
2777
+ tmingos/sassy-roots php
2778
+ OSGConnect/freesurfer_workflow python
2779
+ mirego/hanzo ruby
2780
+ Logicalshift/tame-tree rust
2781
+ bradyholt/aspnet-core-react-template typescript
2782
+ willpatterson/HOPSTACK c
2783
+ bernardolins/clustereasy go
2784
+ fhoeben/hsac-fitnesse-fixtures java
2785
+ manifoldco/torus-cli javascript
2786
+ DNepovim/kraj-praha php
2787
+ aaronkurtz/bricky python
2788
+ ifosch/skyed ruby
2789
+ aptos-labs/aptos-core rust
2790
+ shiftkey/desktop typescript
2791
+ IFTTT/JazzHands c
2792
+ resourced/resourced-master go
2793
+ mrdon/AMPS java
2794
+ dkrathi457/app javascript
2795
+ hernantas/MangaReader php
2796
+ worldforge/libwfut python
2797
+ k0nserv/Humus ruby
2798
+ jzhu98/telescope rust
2799
+ paypac/node-concierge typescript
2800
+ adobe-rnd/cordova-osx c
2801
+ ephemeralsnow/packer go
2802
+ mkarneim/luamod java
2803
+ sigurdga/barteby javascript
2804
+ kjhoerr/august-offensive php
2805
+ churchlab/millstone python
2806
+ matiaskorhonen/libpixel-ruby ruby
2807
+ jonas-schievink/sneeze rust
2808
+ tjoskar/ng2-lazyload-image typescript
2809
+ netzimme/mbed-os c
2810
+ myodc/go-micro go
2811
+ pzn/clipapp java
2812
+ mozilla/webmaker-app-cordova javascript
2813
+ GrottoPress/jentil php
2814
+ asteroide/immo_spider python
2815
+ crepe/creperie ruby
2816
+ snewt/bnf rust
2817
+ Dkendal/battle_snake typescript
2818
+ leovegetium/Trabalho-P c
2819
+ rancher/k3s go
2820
+ holandajunior/workaday java
2821
+ squarewave/addons-frontend javascript
2822
+ anqh/anqh php
2823
+ odoo-chile/l10n_cl_account_vat_ledger python
2824
+ ValiMail/griddler ruby
2825
+ gchp/termbox-sys rust
2826
+ polyaxon/polyaxon typescript
2827
+ k0gaMSX/kcc c
2828
+ lstolyarov/terraform go
2829
+ Syncleus/aparapi java
2830
+ rowanoulton/prefix-matches javascript
2831
+ LaurentEsc/Laravel-Subdomain-Localization php
2832
+ jeenalee/sklearn_pmml python
2833
+ mahimahi42/microblogger ruby
2834
+ minijackson/INF-4301A rust
2835
+ robak86/neography typescript
2836
+ cxd4/trig c
2837
+ ccirello/gochatbot go
2838
+ Arabidopsis-Information-Portal/intermine java
2839
+ escaip/smart_bike javascript
2840
+ symfony-cmf/Resource php
2841
+ attenzione/SublimeLinter-scss-lint python
2842
+ syncrou/manageiq ruby
2843
+ dwrensha/capnproto-rust rust
2844
+ arthot/calque typescript
2845
+ filom/ASN1Decoder c
2846
+ otoolep/raft go
2847
+ apache/jmeter java
2848
+ kiboit/phast javascript
2849
+ vanderlee/PHPSwaggerGen php
2850
+ pudo/spendb python
2851
+ dtan4/c2y ruby
2852
+ qdot/systray-rs rust
2853
+ tsvetie/nativescript-cli typescript
2854
+ kazmasaurus/CRToast c
2855
+ wrapp/wrapplog go
2856
+ malucs-developer/Android-Simulator java
2857
+ bassettmb/slack-bot-dev javascript
2858
+ imabug/raddb php
2859
+ hackebrot/cibopath python
2860
+ ruby/spec ruby
2861
+ dinfuehr/rust rust
2862
+ SaschaNaz/TypeScript typescript
2863
+ greenplum-db/gpdb c
2864
+ v4lproik/no-name go
2865
+ rwinch/spring-security java
2866
+ mzrimsek/resume_site javascript
2867
+ alexweissman/UserFrosting php
2868
+ mokieyue/mopidy python
2869
+ chronogolf/lightspeed_restaurant ruby
2870
+ ajroetker/rustc-serialize rust
2871
+ gund/ng-http-interceptor typescript
2872
+ BGWoodward/FishDetector c
2873
+ melange-app/melange go
2874
+ Team694/joebot java
2875
+ CartoDB/Windshaft-cartodb javascript
2876
+ biplobice/concrete5 php
2877
+ textbook/flask-forecaster python
2878
+ heavenstudio/spree_pag_seguro ruby
2879
+ keeperofdakeys/asn1-rs rust
2880
+ BitGo/BitGoJS typescript
2881
+ bespider/STTweetLabel c
2882
+ asobti/kube-monkey go
2883
+ VinnyQ/blueflood java
2884
+ benefitcloud/ember-uploader javascript
2885
+ wesley1001/Kurogo-Mobile-Web php
2886
+ ncareol/spatialdb python
2887
+ giedomak/table_cloth ruby
2888
+ dati91/servo rust
2889
+ t123yh/simple-sandbox typescript
2890
+ cxa/MenuItemKit c
2891
+ liam-middlebrook/csh-plug go
2892
+ TehSAUCE/imagej java
2893
+ MacPaw/eslint-config-webservices javascript
2894
+ ponkrit/developer-test php
2895
+ fna/owning-a-home-api python
2896
+ lukeredpath/xcodesnippets ruby
2897
+ stepancheg/rust-ide-rust rust
2898
+ trustpilot/skift typescript
2899
+ UrbanCompass/RMGallery c
2900
+ scode/saltybox go
2901
+ sake/bouncycastle-java java
2902
+ intervention-engine/frontend javascript
2903
+ siad007/json-schema php
2904
+ gitpython-developers/GitPython python
2905
+ solidusio-contrib/solidus_easypost ruby
2906
+ bolinfest/serde-jsonrc rust
2907
+ influxdb/influxdb typescript
2908
+ anagromataf/Fountain c
2909
+ Dirbaio/btcd go
2910
+ outofcoffee/testcontainers-java java
2911
+ TripleSpeeder/StandingOrderDapp javascript
2912
+ jimmythongtran/recipe_tracker php
2913
+ spyder-ide/qtawesome python
2914
+ samvera/hyrax ruby
2915
+ habitat-sh/habitat rust
2916
+ j-f1/forked-desktop typescript
2917
+ CollegeBart/bart-sdl-engine-e16 c
2918
+ StroblIndustries/codeutilsShared go
2919
+ inbloom/secure-data-service java
2920
+ tidepool-org/blip javascript
2921
+ burnflare/CrowdBuy php
2922
+ ravel-net/ravel python
2923
+ postmodern/kramdown-man ruby
2924
+ oxcable/oxcable rust
2925
+ zentol/flink typescript
2926
+ Gluttton/PslRK c
2927
+ elwinar/adeptus go
2928
+ kaltsimon/Chasing-Pictures-front-end java
2929
+ bitclaw/apptmnt javascript
2930
+ jeffersonmartin/code-examples php
2931
+ humangeo/preflyt python
2932
+ julik/mal ruby
2933
+ mneumann/expression-rs rust
2934
+ thehyve/glowing-bear typescript
2935
+ robertmaynard/Sandbox c
2936
+ mrekucci/euler go
2937
+ HubSpot/jinjava java
2938
+ pd4d10/tiza javascript
2939
+ listabierta/census-ahoraencomun php
2940
+ ucb-sts/sts python
2941
+ backus/guard-rubocop ruby
2942
+ ggez/ggez rust
2943
+ dl988/quedro typescript
2944
+ mk12/morse c
2945
+ didip/tollbooth go
2946
+ smalecki/motech java
2947
+ dtekcth/dfotose javascript
2948
+ mdlayher/wavepipe php
2949
+ jlaunonen/kirppu python
2950
+ dhensby/silverstripe-cms ruby
2951
+ exe-dealer/rust-md5 rust
2952
+ goloveychuk/tsruntime typescript
2953
+ rubenk/burp c
2954
+ opencontainers/runc go
2955
+ kits-ab/gakusei java
2956
+ virtool/virtool javascript
2957
+ phalcon/zephir php
2958
+ matthiask/towel python
2959
+ slate-studio/openapi-rails ruby
2960
+ lowRISC/opentitan rust
2961
+ dsebastien/DefinitelyTyped typescript
2962
+ HalCanary/skia-hc c
2963
+ mongrelion/gapp go
2964
+ openmhealth/sample-data-generator java
2965
+ amos-ws16/amos-ws16-arrowjs-server javascript
2966
+ edvinaskrucas/counter-laravel php
2967
+ jmiserez/sts python
2968
+ amatsuda/nested_scaffold ruby
2969
+ tsion/miri rust
2970
+ sgtoj/cw-manage-slack-bot typescript
2971
+ mlaz/mynewt-core c
2972
+ buchgr/bazel-remote go
2973
+ pilot51/voicenotify java
2974
+ eJRF/ejrf javascript
2975
+ stof/symfony php
2976
+ teonlamont/mne-python python
2977
+ twitter/twurl ruby
2978
+ dylanmckay/protocol rust
2979
+ amalshehu/angular-tour-of-heroes typescript
2980
+ thomaskeck/root c
2981
+ flynn-examples/go-flynn-example go
2982
+ Microsoft/ApplicationInsights-Android java
2983
+ mrkmarron/ChakraCore javascript
2984
+ engram-design/FieldManager php
2985
+ EinsamHauer/graphite-web-iow python
2986
+ gina-alaska/ttnmanager ruby
2987
+ Boddlnagg/rustup.rs rust
2988
+ cannoneyed/fiddle typescript
2989
+ dslab-epfl/asap c
2990
+ go-playground/generate go
2991
+ proxer/ProxerLibJava java
2992
+ sgmap/mes-aides-ui javascript
2993
+ jolantis/artlantis php
2994
+ OCA/contract python
2995
+ rasnom/sorryyoufeelthatway ruby
2996
+ dtolnay/cxx rust
2997
+ formigio/angular-frontend typescript
2998
+ mundue/MMTrackingController c
2999
+ guildencrantz/ask_nest go
3000
+ hpautonomy/find java
3001
+ shioyang/EmotionalReader javascript
3002
+ atehnix/laravel-stubs php
3003
+ spreadflow/spreadflow-core python
3004
+ costolo/chain ruby
3005
+ pacman82/odbc-sys rust
3006
+ github/webauthn-json typescript
3007
+ coreboot/chrome-ec c
3008
+ projectatomic/buildah go
3009
+ helun/Ektorp java
3010
+ cysjonathan/coursemology2 javascript
3011
+ webfactory/content-mapping-sourceadapter-propel php
3012
+ djangogirlstaipei/eshop python
3013
+ benwbrum/fromthepage ruby
3014
+ adRichter/plantex rust
3015
+ artivilla/desktop typescript
3016
+ deniscostadsc/playground c
3017
+ willfaught/gockle go
3018
+ danshannon/javastrava-test java
3019
+ coryhouse/react-slingshot javascript
3020
+ sparkframework/spark php
3021
+ 99designs/colorific python
3022
+ r7kamura/altria-simple_cov ruby
3023
+ nathanrosspowell/rust_guessing_game rust
3024
+ murmur76/beyond.ts typescript
3025
+ abusalimov/SublimeCImproved c
3026
+ Versent/saml2aws go
3027
+ QuickBlox/quickblox-android-sdk java
3028
+ Jameskmonger/dependument javascript
3029
+ LogicAndTrick/twhl php
3030
+ revng/llvmcpy python
3031
+ eric/metriks_log_webhook ruby
3032
+ mulkieran/stratisd rust
3033
+ BillWagner/WorkingWithTypeScript typescript
3034
+ ferrous26/cs452-flaming-meme c
3035
+ rootulp/exercism go
3036
+ smalldatalab/omh-dsu java
3037
+ dimkarakostas/unimeet javascript
3038
+ symfony/security-bundle php
3039
+ Antrikshy/reddit2Kindle python
3040
+ moneyadviceservice/middleman-i18n-markdown ruby
3041
+ tzkhan/roman-rust rust
3042
+ xtina-starr/reaction typescript
3043
+ thoughtbot/BotKit c
3044
+ ziutek/thread go
3045
+ rajdavies/fabric8 java
3046
+ vigetlabs/microcosm javascript
3047
+ whathejoe/lms-m4g4 php
3048
+ foliant-docs/foliant python
3049
+ mongodb/mongoid ruby
3050
+ burtonageo/rebind rust
3051
+ wishtack/wishtack-steroids typescript
3052
+ aaronriekenberg/openbsd_cproxy c
3053
+ ftcjeff/AirlineCode-go go
3054
+ RoboZonky/robozonky java
3055
+ dmitriiabramov/esfmt javascript
3056
+ artesaos/laravel-linkedin php
3057
+ estebistec/django-twitter-bootstrap python
3058
+ aruprakshit/sync ruby
3059
+ zslayton/cron rust
3060
+ dkocich/osm-pt-ngx-leaflet typescript
3061
+ pressel/mpi4py c
3062
+ anthonyrego/gosmf go
3063
+ Charling-Huang/birt java
3064
+ hellsgate1001/waypoints javascript
3065
+ renyuneyun/core php
3066
+ Antojitos/chalupas python
3067
+ Validic/validic ruby
3068
+ mijnadres/serde_elm rust
3069
+ artsy/force-public typescript
3070
+ reupen/mmh c
3071
+ btobolaski/terraform-provider-linode go
3072
+ bogdansolga/nokia-spring-boot-training java
3073
+ testlnord/wurfelspiel javascript
3074
+ fullybaked/pslackr php
3075
+ MasonM/hssonline-conference python
3076
+ pch/lastfm-client ruby
3077
+ oakes/neovim-rs rust
3078
+ cookingfox/stibble-api-client-angular typescript
3079
+ hikoLab/pebcessing c
3080
+ soudy/eparser go
3081
+ yingyun001/ovirt-engine java
3082
+ mg4tv/mg4tv-web javascript
3083
+ tux-rampage/zend-di php
3084
+ 2baOrNot2ba/dreamBeam python
3085
+ chrisvanheuveln/cisco-network-node-utils ruby
3086
+ DaGenix/rust-crypto rust
3087
+ jordwest/news-feed-eradicator typescript
3088
+ ytaben/WakeOnLanRelay c
3089
+ mattn/go-mastodon go
3090
+ steria/skuldsku java
3091
+ cristiana214/cristianachavez214-cristianachavez javascript
3092
+ ob-ivan/sd-currency php
3093
+ k4nar/inbox python
3094
+ chrishunt/github-auth ruby
3095
+ tum-rt/emoji-feedback rust
3096
+ thecjharries/slim-ace typescript
3097
+ bbockelm/condor-network-accounting c
3098
+ qskycolor/gofrontend go
3099
+ Monospark/ActionControl java
3100
+ slightly-askew/portfolio-2017 javascript
3101
+ digitickets/omnipay-verifone-web-service php
3102
+ ctsit/nacculator python
3103
+ emodeqidao/Kiwi ruby
3104
+ aopicier/cryptopals-rust rust
3105
+ sdeleuze/mixit typescript
3106
+ fergul/Cache c
3107
+ declanshanaghy/bbqberry go
3108
+ Hypersonic/Starlorn java
3109
+ var-bin/reactjs-training javascript
3110
+ joshmassey/sga-itracker php
3111
+ kytos/python-openflow python
3112
+ spatchcock/calc-json-ruby ruby
3113
+ bitwalker/rustcalc rust
3114
+ what3words/w3w-node-wrapper typescript
3115
+ GNOME/telepathy-account-widgets c
3116
+ resumic/schema go
3117
+ kryptnostic/rhizome java
3118
+ topherauyeung/portfolio javascript
3119
+ EOL/eol_php_code php
3120
+ victorpoluceno/xwing python
3121
+ jiajiawang/load_more ruby
3122
+ hoodie/rust-email rust
3123
+ jchakra/discord-raider typescript
3124
+ k4rtik/btp-gvn c
3125
+ torinos-io/api go
3126
+ veyndan/paper-for-reddit java
3127
+ alphagov/notifications-admin javascript
3128
+ ProjetPP/PPP-Wikidata php
3129
+ Stratoscale/skipper python
3130
+ uhoh-itsmaciek/pg-quilter ruby
3131
+ cobalt-org/cobalt.rs rust
3132
+ Ragg-/Delir typescript
3133
+ ROCm-Developer-Tools/HIP c
3134
+ hashicorp/go-getter go
3135
+ philipphager/disclosure-android-app java
3136
+ jlord/git-it-electron javascript
3137
+ armadito/armadito-glpi php
3138
+ SUSE/azurectl python
3139
+ kolorahl/acls ruby
3140
+ LesPepitos/gist rust
3141
+ neild3r/vscode-php-docblocker typescript
3142
+ matayoshi/tools c
3143
+ emicklei/melrose go
3144
+ CA-APM/ca-apm-fieldpack-asm java
3145
+ dev-brutus/427 javascript
3146
+ sabre-io/vobject php
3147
+ pinax/django-waitinglist python
3148
+ logentries/le_ruby ruby
3149
+ jhelwig/homers rust
3150
+ chunye/azure-functions-ux typescript
data/qna/aligned6_qna.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
data/qna/repo_scoped_qa.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
data/repo_list.txt ADDED
@@ -0,0 +1,800 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ imankulov/sentry
2
+ rnyberg/pyfibot
3
+ artefactual/archivematica-history
4
+ caleb531/automata
5
+ Antiun/account-invoicing
6
+ ElementalAlchemist/txircd
7
+ kmee/stock-logistics-warehouse
8
+ BT-rmartin/partner-contact
9
+ yuzie007/upho
10
+ bfaludi/daprot
11
+ angr/cle
12
+ jmenglund/CollectionBatchTool
13
+ coleifer/scout
14
+ hsercanatli/adaptivetuning
15
+ krmaxwell/TRX
16
+ svieira/Flask-HipPocket
17
+ capybaralet/fuel
18
+ openstack/akanda-rug
19
+ glyph/txsni
20
+ tiddlyweb/tiddlywebplugins.atom
21
+ grimwm/py-dictobj
22
+ amorison/qjobs
23
+ blancltd/blanc-basic-pages
24
+ zchee/python-client
25
+ CBitLabs/django-globals
26
+ rgardner/ouimeaux
27
+ hsolbrig/SNOMEDToOWL
28
+ kevinschaul/open-in-github
29
+ TangledWeb/tangled.auth
30
+ bbangert/retools
31
+ czpython/aldryn-faq
32
+ alama/PSO2Proxy
33
+ 10gen-labs/mongo-connector
34
+ makinacorpus/reportlab-ecomobile
35
+ devinmcgloin/advent
36
+ problemshift/kf5py
37
+ PyO3/setuptools-rust
38
+ apoorvemohan/haas
39
+ crsmithdev/arrow
40
+ c4fcm/CLIFF-API-Client
41
+ martinrusev/imbox
42
+ favien/favien
43
+ thomwiggers/django-mongodbforms
44
+ anthonysandrin/kafka-utils
45
+ dplucenio/heat_diffusion_experiment
46
+ bgyori/bioagents
47
+ plainas/tq
48
+ vesln/robber.py
49
+ dirn/Simon
50
+ plone/plone.server
51
+ lauft/timew-report
52
+ AmiiThinks/amii-tf-nn
53
+ ludwiktrammer/django-tagging-autocomplete
54
+ pyinvoke/invocations
55
+ jaylett/django_exceptional_middleware
56
+ nosamanuel/dj-queryset-manager
57
+ ap--/python-oceanoptics
58
+ millerdev/django-nose
59
+ ssanderson/interface
60
+ ryanraaum/oldowan.mtdna
61
+ oemof/feedinlib
62
+ madmaze/pytesseract
63
+ timraasveld/ansible-string-split-filter
64
+ otknoy/michishiki_api_server
65
+ alexmilesyounger/ds_basics
66
+ adampiskorski/lpr_poc
67
+ ranisalt/enigma
68
+ infOpen/ansible-role-vsftpd
69
+ chubbymaggie/asap
70
+ girder/girder_worker
71
+ atiberghien/makerscience-server
72
+ KuChanTung/Python
73
+ globocom/database-as-a-service
74
+ Stark-Mountain/meetup-facebook-bot
75
+ claudiopastorini/claudiopastorini.github.io
76
+ b123400/purescript-ide-sublime
77
+ bshaffer/appengine-python-vm-hello
78
+ chop-dbhi/django-webhooks
79
+ jwarshaw/RaspberryDrive
80
+ aikramer2/spaCy
81
+ alexgarciac/scrapi
82
+ karel-brinda/prophyle
83
+ etataurov/pytest
84
+ khchine5/opal
85
+ hatbot-team/hatbot_resources
86
+ ellmetha/machina-singlepageapp
87
+ seibert/numba
88
+ earlwlkr/POICrawler
89
+ ideascube/ideascube
90
+ group-policy/rally
91
+ funkybob/paws
92
+ analyst-collective/dbt
93
+ scanner-research/scanner
94
+ ScanOC/trunk-player
95
+ saltstack/salt
96
+ cherba/apitools
97
+ RainCity471/lyCompiler
98
+ chiphogg/vim-vtd
99
+ patrickspencer/mathdeck
100
+ brainwane/zulip
101
+ handroll/handroll
102
+ sl2017/campos
103
+ wiliamsouza/hystrix-py
104
+ dimagi/commcare-hq
105
+ thiderman/network-kitten
106
+ kefir500/ghstats
107
+ JungeAlexander/cocoscore
108
+ ohsu-qin/qipipe
109
+ sergey-dryabzhinsky/dedupsqlfs
110
+ t-miyamae/teuthology
111
+ 0xPoly/ooni-probe
112
+ sorgerlab/indra
113
+ nvbn/thefuck
114
+ aosp-mirror/platform_external_skia
115
+ masasin/spirit
116
+ benedicteb/outcast
117
+ SEL-Columbia/commcare-hq
118
+ OCA/stock-logistics-warehouse
119
+ lemming52/white_knight
120
+ egafford/sahara
121
+ jdevera/subdue
122
+ VirusTotal/misp-modules
123
+ benedfit/SublimeLinter-contrib-pug-lint
124
+ thebinarypenguin/SublimeLinter-contrib-raml-cop
125
+ csrocha/account_journal_payment_subtype
126
+ pombreda/seascope
127
+ tanayseven/personal_website
128
+ pinry/pinry
129
+ geelweb/laposte-python-sdk
130
+ phil-lopreiato/the-blue-alliance
131
+ EnvGen/toolbox
132
+ openaustralia/publicwhip-matthew
133
+ thorgate/django-project-template
134
+ monostable/haskell-kicad-data
135
+ OpenSpace/OpenSpace
136
+ planetlabs/datalake-ingester
137
+ yamatt/bonfiremanager
138
+ wkentaro/chainer
139
+ Dybov/real_estate_agency
140
+ Astroua/aws_controller
141
+ nagilum/script.rndmov
142
+ lsgunth/rapidsms
143
+ yeasy/robot_tool
144
+ ShivamSarodia/ShivyC
145
+ stefanklug/plata
146
+ willdavidc/piel
147
+ henriquebastos/virtualenv-bootstrap
148
+ ianfieldhouse/number_to_words
149
+ sindrig/spoppy
150
+ rlee287/pyautoupdate
151
+ bharling/django-pint
152
+ jackromo/RandTerrainPy
153
+ ayushgoel/LongShot
154
+ reedstrm/Pyrseas
155
+ andylytical/brewpi-scripts
156
+ HHS-IntroProgramming/Multiplication-table
157
+ wyager/IHaskell
158
+ opnfv/functest
159
+ amolenaar/gaphor
160
+ potatolondon/contentious
161
+ pavel-paulau/perfrunner
162
+ AlexHill/mezzanine
163
+ sassoftware/mint
164
+ hackerspace-ntnu/website
165
+ paylogic/py2deb
166
+ oliverlee/antlia
167
+ voer-platform/vp.repo
168
+ exekias/django-achilles
169
+ ikaruswill/vector-space-model
170
+ goldmann/docker-scripts
171
+ tzengyuxio/python-five91
172
+ Doist/todoist-python
173
+ datasciencebr/serenata-toolbox
174
+ jeanmask/opps-admin
175
+ fprimex/zdesk
176
+ praekelt/go-contacts-api
177
+ MisanthropicBit/bibpy
178
+ thismachinechills/save_skype
179
+ lucianovdveekens/jiradoc
180
+ ckan/ckanext-qa
181
+ hyunchel/redis-dump-load
182
+ ondergetekende/python-panavatar
183
+ tarpas/pytest-testmon
184
+ yola/proxyprefix
185
+ ScatterHQ/eliot
186
+ NewKnowledge/punk
187
+ rdo-management/ironic-discoverd
188
+ igstan/redis-grep
189
+ opencord/voltha
190
+ xandr2/blynkapi
191
+ exoanalytic/python-skyfield
192
+ hobarrera/django-afip
193
+ Connexions/cnx-publishing
194
+ Charcoal-SE/SmokeDetector
195
+ pfmoore/invoke
196
+ Calysto/metakernel
197
+ CCI-MOC/GUI-Backend
198
+ harvard-lil/h2o
199
+ binoculars/osf.io
200
+ kjordahl/swm
201
+ tomv564/LSP
202
+ thomasballinger/tmuxp
203
+ philipdexter/vx
204
+ OnroerendErfgoed/crabpy
205
+ gviot/nadis
206
+ moreati/b-prefix-all-the-doctests
207
+ rudeb0t/DjangoAllowDeny
208
+ bodbdigr/restea
209
+ 7ws/django-emailer
210
+ mandiant/ioc_writer
211
+ cloudify-cosmo/tosca-vcloud-plugin
212
+ alisaifee/flask-limiter
213
+ xmunoz/sodapy
214
+ mass-project/mass_api_client
215
+ gsarma/ChannelWorm
216
+ markbrough/exchangerates
217
+ TangledWeb/tangled.sqlalchemy
218
+ FlipperPA/wagtailpress
219
+ TangledWeb/tangled.website
220
+ sedders123/phial
221
+ JrGoodle/clowder
222
+ kevgathuku/top40
223
+ erikrose/blessings
224
+ yola/auth_tkt
225
+ consbio/parserutils
226
+ archsh/tg2ext.express
227
+ MichaelYusko/Bot-Chucky
228
+ ryanmcdermott/birdseed
229
+ mociepka/saleor
230
+ GallopLabs/facebook-ads-api
231
+ rail/releasetasks
232
+ sebdah/yayson
233
+ serge-sans-paille/gast
234
+ adlibre/django-bcp
235
+ ayushgoel/mstranslator
236
+ gilesbrown/python-icapservice
237
+ nigma/dj-cmd
238
+ srittau/rouver
239
+ VirgilSecurity/virgil-sdk-python
240
+ verilylifesciences/analysis-py-utils
241
+ compunova/kozinaki
242
+ wangjohn/zinc_cli
243
+ SCUEvals/scuevals-api
244
+ ifduyue/urlfetch
245
+ cychiang/mafan
246
+ mcmtroffaes/pathlib2
247
+ tilezen/scoville
248
+ pczerkas/captainhook
249
+ benedictpaten/cactus
250
+ caktus/django-pagelets
251
+ suminb/urwid-stackedwidget
252
+ alphagov/stagecraft
253
+ Connexions/cnx-authoring
254
+ agoragames/py-eventsocket
255
+ evoja/docker-Github-Gitlab-Auto-Deploy
256
+ incuna/feincms-extensions
257
+ zmbq/djqgrid
258
+ kevinconway/rpmvenv
259
+ maxzheng/workspace-tools
260
+ thsnr/gygax
261
+ theislab/dca
262
+ iamwucheng/xml_models2
263
+ divio/django-cas
264
+ johnpaulett/txHL7
265
+ twig/django-taggit
266
+ gasman/Willow
267
+ smarkets/statprof
268
+ 360youlun/cmsplugin-bootstrap-carousel
269
+ ceball/param
270
+ associazionepoltronieri/blender-ap
271
+ wikilinks/sift
272
+ DesertBot/DesertBot
273
+ 4degrees/segue
274
+ holdenweb/nbtools
275
+ openhealthcare/opal-referral
276
+ BansheeMediaPlayer/bockbuild
277
+ elacuesta/scrapy
278
+ mbr/flask-appconfig
279
+ ninjawil/weather-station
280
+ sunlightlabs/thezombies
281
+ PanDAWMS/panda-bigmon-atlas
282
+ varunarya10/oslo.i18n
283
+ jefrailey/basic-scraper
284
+ udibr/fuel
285
+ haridsv/fabric
286
+ gadventures/gapipy
287
+ sk-/python2.7-type-annotator
288
+ mythmon/kitsune
289
+ j4mie/django-activelink
290
+ jwg4/flask-autodoc
291
+ EmadMokhtar/halaqat
292
+ EDUlib/edx-platform
293
+ Graylog2/graylog-ansible-role
294
+ armab/st2contrib
295
+ KrzysztofSendor/dactyl
296
+ nurav/balrog
297
+ Pierre-Sassoulas/django-survey
298
+ microsoft/dpu-utils
299
+ PersonalGenomesOrg/open-humans
300
+ vayan/external-video
301
+ simonjbeaumont/xcp-rrdd
302
+ lozadaOmr/ansible-admin
303
+ ulikoehler/UliEngineering
304
+ kxxoling/fabric
305
+ EmilStenstrom/nephele
306
+ chingc/DJRivals
307
+ docsbox/docsbox
308
+ uva-financial-engineering/cifer-tournament
309
+ OSGConnect/freesurfer_workflow
310
+ aaronkurtz/bricky
311
+ worldforge/libwfut
312
+ churchlab/millstone
313
+ asteroide/immo_spider
314
+ odoo-chile/l10n_cl_account_vat_ledger
315
+ jeenalee/sklearn_pmml
316
+ attenzione/SublimeLinter-scss-lint
317
+ pudo/spendb
318
+ hackebrot/cibopath
319
+ mokieyue/mopidy
320
+ textbook/flask-forecaster
321
+ ncareol/spatialdb
322
+ fna/owning-a-home-api
323
+ gitpython-developers/GitPython
324
+ spyder-ide/qtawesome
325
+ ravel-net/ravel
326
+ humangeo/preflyt
327
+ ucb-sts/sts
328
+ jlaunonen/kirppu
329
+ matthiask/towel
330
+ jmiserez/sts
331
+ teonlamont/mne-python
332
+ EinsamHauer/graphite-web-iow
333
+ OCA/contract
334
+ spreadflow/spreadflow-core
335
+ djangogirlstaipei/eshop
336
+ 99designs/colorific
337
+ revng/llvmcpy
338
+ Antrikshy/reddit2Kindle
339
+ foliant-docs/foliant
340
+ estebistec/django-twitter-bootstrap
341
+ Antojitos/chalupas
342
+ MasonM/hssonline-conference
343
+ 2baOrNot2ba/dreamBeam
344
+ k4nar/inbox
345
+ ctsit/nacculator
346
+ kytos/python-openflow
347
+ victorpoluceno/xwing
348
+ Stratoscale/skipper
349
+ SUSE/azurectl
350
+ pinax/django-waitinglist
351
+ paulfanelli/planet_alignment
352
+ jmcclell/django-bootstrap-pagination
353
+ SUNET/eduid-webapp
354
+ jiaaro/pydub
355
+ srittau/python-htmlgen
356
+ marcoslhc/xyvio
357
+ zestyping/q
358
+ epsy/clize
359
+ lawlesst/vivo-rdflib-sparqlstore
360
+ storecast/barrel
361
+ mwilliamson/whack
362
+ toastdriven/restless
363
+ Empiria/matador
364
+ daltonserey/tst
365
+ whilp/python-script
366
+ smly/ume
367
+ richo/groundstation
368
+ MetaMemoryT/aiozmq
369
+ Z2PackDev/TBmodels
370
+ igordejanovic/textX
371
+ pbs/cmsplugin-filer
372
+ google/python-lakeside
373
+ jbergant/endpoints-proto-datastore
374
+ cqse/teamscale-client-python
375
+ f00f-nyc/cityhall-python
376
+ ProjetPP/ExamplePPPModule-Python
377
+ cjhutto/bsd
378
+ svanoort/pyresttest
379
+ pmclanahan/urlwait
380
+ durden/nikeplus
381
+ veo-labs/nose-progressive
382
+ isghe/chainpoint
383
+ AndBicScadMedia/blueprint
384
+ garydonovan/google-maps-services-python
385
+ infoxchange/ixwsauth
386
+ andrasmaroy/pconf
387
+ aditweb/django-socialregistration
388
+ bugra/l1
389
+ eugeniy/pytest-tornado
390
+ juanriaza/django-rest-framework-msgpack
391
+ justin8/portinus
392
+ mayfield/ecmcli
393
+ saulshanabrook/django-simpleimages
394
+ williamboman/matrix-angular-sdk
395
+ FutureSharks/invokust
396
+ nitishr/PyHamcrest
397
+ nvdv/vprof
398
+ luci/recipes-py
399
+ freevoid/yawf
400
+ christopher18/Celsearch
401
+ lpancescu/atlas-lint
402
+ alexm92/sentry
403
+ petrjasek/superdesk-ntb
404
+ mpkato/interleaving
405
+ kapadia/rasterio
406
+ gbouvignies/chemex
407
+ google/nogotofail
408
+ sapcc/monasca-agent
409
+ bert9bert/statsmodels
410
+ mopidy/mopidy-soundcloud
411
+ scrapinghub/shub
412
+ alexef/pygobject
413
+ talons/talons
414
+ easy-as-python/django-webmention
415
+ ryankask/django-discoverage
416
+ davidfischer/warehouse
417
+ idjaw/netman
418
+ rahulbohra/Python-Basic
419
+ eriol/circuits
420
+ sarutobi/ritmserdtsa
421
+ eunchong/build
422
+ DistributedSystemsGroup/zoe
423
+ citrix-openstack-build/oslo.versionedobjects
424
+ lamby/debian-devel-changes-bot
425
+ suclearnub/discordgrapher
426
+ samcheck/PyMedia
427
+ stepan-perlov/pgup
428
+ rootulp/exercism
429
+ larrybradley/photutils
430
+ osahp/forecastonishing
431
+ alphagov/notifications-api
432
+ onitake/Uranium
433
+ keybar/keybar
434
+ richard-willdooit/odoo-product-configurator
435
+ taeram/idiocy
436
+ leaffan/pynhldb
437
+ liumengjun/django-static-precompiler
438
+ derricw/asciisciit
439
+ AliGhahraei/nao-classroom
440
+ ChromeDevTools/devtools-frontend
441
+ allenai/deep_qa
442
+ brightchen/Impala
443
+ pyhmsa/pyhmsa-gui
444
+ jpbottaro/anna
445
+ scolby33/OCSPdash
446
+ guillaume-philippon/aquilon
447
+ stefan-caraiman/cloudbase-init-ci
448
+ fwalch/python-client
449
+ google/skia-buildbot
450
+ MarquisLP/gamehappy
451
+ paolodedios/tensorflow
452
+ abanaiyan/sniper
453
+ watchdogpolska/bliski_publikator
454
+ openego/oeplatform
455
+ jaapverloop/massa
456
+ mvexel/maproulette
457
+ atindale/business-glossary
458
+ ionitadaniel19/testframeworksevolution
459
+ rth/PyAbel
460
+ sunng87/jip
461
+ delinhabit/django-rest-framework
462
+ sampadsaha5/sympy
463
+ josephbisch/the-blue-alliance
464
+ globus/globus-cli
465
+ muun/bitforge
466
+ josuemontano/api-starter
467
+ ged/mongrel2
468
+ L1ghtn1ng/usaf
469
+ torchbox/wagtail
470
+ adrienbrunet/fanfare_cuc
471
+ homeworkprod/byceps
472
+ SalesforceFoundation/Cumulus
473
+ seler/djoauth2
474
+ ryan-roemer/django-cloud-browser
475
+ atheiste/django-bit-category
476
+ SUNET/SATOSA
477
+ jonathanslenders/python-prompt-toolkit
478
+ CompassionCH/compassion-switzerland
479
+ srct/whats-open
480
+ StackStorm/st2
481
+ HIIT/hybra-core
482
+ GuillaumeDerval/INGInious
483
+ kwagyeman/openmv
484
+ pradyunsg/pip
485
+ benschmaus/catapult
486
+ shubhamdhama/zulip
487
+ ministryofjustice/cla_backend
488
+ puttarajubr/commcare-hq
489
+ oldani/nanodegree-blog
490
+ hmoco/osf.io
491
+ gamezdaniel/mswl-dt-2013
492
+ LINKIWI/linkr
493
+ rtrembecky/roots
494
+ appliedx/edx-platform
495
+ zimolzak/Raspberry-Pi-newbie
496
+ OpenTreeOfLife/phylesystem-api
497
+ AlexandreProenca/backend-morandofloripa
498
+ msultan/mdtraj
499
+ kwadraterry/GPGPU-LUT
500
+ conjure-up/conjure-up
501
+ mattstibbs/blockbuster-server
502
+ mvpgomes/shopit-app
503
+ svetlyak40wt/django-dzenlog
504
+ mariocesar/django-rocket
505
+ madebymany/isthetoiletfree
506
+ DeBortoliWines/Bika-LIMS
507
+ xcgd/account_streamline
508
+ 1flow/1flow
509
+ redhat-developer-tooling/vagrant-installers
510
+ SanaMobile/sana.protocol_builder
511
+ Foxboron/Frank
512
+ AustinRochford/s3img-ipython-magic
513
+ victorhahncastell/atlassian_permissions
514
+ maxamillion/autocloud
515
+ MrHarcombe/python-gpiozero
516
+ UMD-DRASTIC/drastic
517
+ OpenTreeOfLife/opentree
518
+ pegasus-isi/pegasus
519
+ gdit-cnd/RAPID
520
+ Floobits/plugin-common-python
521
+ cpcloud/dynd-python
522
+ Authentise/git-release
523
+ israelg99/eva
524
+ openxc/openxc-python
525
+ solidrails/mongrel2
526
+ jwg4/qual
527
+ sonofatailor/django-oscar
528
+ stoeps13/ibmcnx2
529
+ Vnet-as/falcon-hateoas
530
+ azaroth42/iiif-harvester
531
+ montefra/dodocs
532
+ MarkusH/django-nap
533
+ uccser/cs4teachers
534
+ veatch/elasticsearch-py
535
+ sdg-mit/gitless
536
+ cjcardinale/climlab
537
+ sorgerlab/belpy
538
+ OCA/reporting-engine
539
+ tylerdave/devpi-builder
540
+ onepercentclub/onepercentclub-site
541
+ AtteqCom/zsl
542
+ mitar/django-mongo-auth
543
+ LinuxTeam-teilar/cronos.teilar.gr
544
+ boklm/tbb-testsuite
545
+ jr-garcia/AssimpCy
546
+ sussexstudent/falmer
547
+ meebo/greins
548
+ GuidoBR/python-skyfield
549
+ cfobel/si-prefix
550
+ jaraco/irc
551
+ misttechnologies/selenium
552
+ wicksy/laptop-build
553
+ maxsocl/oldmailer
554
+ mchelem/cref2
555
+ anttipalola/alexa
556
+ bopo/django-socialregistration
557
+ percyfal/snakemake-rules
558
+ GaretJax/sphinx-autobuild
559
+ IL2HorusTeam/il2fb-ds-airbridge
560
+ caktus/rapidsms-decisiontree-app
561
+ timhberry/openam-flask-decorator
562
+ nryant/twokenize_py
563
+ lazygunner/xunleipy
564
+ novafloss/populous
565
+ mdmintz/SeleniumBase
566
+ Linaro/lava-server
567
+ PSU-OIT-ARC/django-arcutils
568
+ openstack/nova
569
+ willy-claes/django-react
570
+ Jitsusama/lets-do-dns
571
+ nerevu/riko
572
+ alphagov/performanceplatform-collector
573
+ aymara/verbenet-editor
574
+ rcmachado/pysuru
575
+ achabotl/pambox
576
+ BakeCode/performance-testing
577
+ frx0119/django-orderable-inlines
578
+ thaim/ansible
579
+ minoue/miExecutor
580
+ zolech/zabbix-mesos-template
581
+ mperignon/bmi-delta
582
+ praekelt/molo-gem
583
+ YeoLab/anchor
584
+ slashk/goldstone-server
585
+ DataDog/dogapi
586
+ ioO/billjobs
587
+ globocom/dbaas-zabbix
588
+ Khilo84/Py-StackExchange
589
+ philgyford/django-ditto
590
+ metachris/py2app
591
+ hhursev/recipe-scraper
592
+ myles/me-api
593
+ eXma/meet-and-eat-registration-system
594
+ ryansturmer/gitmake
595
+ kmike/django-widget-tweaks
596
+ CO600GOL/Game_of_life
597
+ grigorisg9gr/pyutils
598
+ jambonrose/DjangoUnleashed-1.8
599
+ aflc/editdistance
600
+ kwhanalytics/rdtools
601
+ ekumenlabs/terminus
602
+ fanglinfang/myuw
603
+ sixty-north/python-transducers
604
+ mozilla/normandy
605
+ andialbrecht/sentry-comments
606
+ Alem/django-jfu
607
+ sloede/pyglab
608
+ agarone-mm/scholastic-demo
609
+ vintasoftware/cdrf.co
610
+ FreeMusicNinja/api.freemusic.ninja
611
+ rmoorman/qotr
612
+ timvandermeij/sentiment-analysis
613
+ chipx86/reviewboard
614
+ hotpxl/canonicalization-server
615
+ caktus/rapidsms-tropo
616
+ samuel/kokki
617
+ DemocracyClub/electionleaflets
618
+ renalreg/radar
619
+ germn/python-for-android
620
+ zsiciarz/django-pgallery
621
+ jokimies/django-pj-budget
622
+ lises/sheldon
623
+ caseyjlaw/flaskigm
624
+ mininet/mininet
625
+ registerguard/django-newswall
626
+ ibackus/custom_python_packages
627
+ madr/utsokt
628
+ building4theweb/soundem-api
629
+ shichao-an/soundmeter
630
+ phss/notes-cli
631
+ euanlau/django-betainvite
632
+ bow/pytest-pipeline
633
+ alejandrodob/mamba
634
+ dudepare/bedrock
635
+ MidwestFurryFandom/mff-rams-plugin
636
+ Teknologforeningen/teknologr.io
637
+ christophmeissner/lagesonum
638
+ nickodell/morse-code
639
+ 0101/djangoembed
640
+ caktus/django-opendebates
641
+ TUD-OS/gem5-dtu
642
+ Commonists/CommonsDownloader
643
+ kalaboster/stringer
644
+ alphagov/digitalmarketplace-api
645
+ nerdzeu/NERDZCrush
646
+ hgl888/chromium-crosswalk-efl
647
+ opencivicdata/scrapers-ca
648
+ rapidpro/casepro
649
+ alphagov/digitalmarketplace-admin-frontend
650
+ eliteraspberries/minipkg
651
+ gogoair/foremast
652
+ spgill/bitnigma
653
+ jberkenbilt/qpdf
654
+ stephenmcd/hg-github
655
+ maximkulkin/marshmallow
656
+ tdphillips/campaigns
657
+ jinty/van.contactology
658
+ matslindh/kimochi-consumer
659
+ honnibal/spaCy
660
+ botify-labs/python-simple-workflow
661
+ damonkelley/django-name
662
+ kfdm/promgen
663
+ us-ignite/us_ignite
664
+ sassoftware/rbm
665
+ rutube/djonet
666
+ HKuz/Test_Code
667
+ Yelp/paasta
668
+ bogdal/freepacktbook
669
+ OpenMined/PySyft
670
+ daniell/django-import-export
671
+ opennode/nodeconductor
672
+ DataViva/dataviva-site
673
+ WalkingMachine/sara_behaviors
674
+ astronaut1712/taiga-back
675
+ laurentbristiel/robotframework-needle
676
+ mpirnat/django-tutorial-v2
677
+ brosner/django-notification
678
+ rsalmaso/django-allauth
679
+ zzz0072/Python_Exercises
680
+ Alweezy/alvin-mutisya-dojo-project
681
+ CAPU-ENG/CAPUHome-API
682
+ MoyTW/RL_Arena_Experiment
683
+ bowen0701/algorithms_data_structures
684
+ murphyke/avocado
685
+ praba230890/junction
686
+ yanqd0/csft
687
+ zimolzak/poker-experiments
688
+ eliran-stratoscale/rackattack-api
689
+ mrlolethan/MinecraftUsernameToUUID
690
+ OPWEN/opwen-webapp
691
+ uvNikita/appstats
692
+ cropleyb/pentai
693
+ gunthercox/ChatterBot
694
+ andburn/python-unitypack
695
+ PnEcrins/GeoNature
696
+ onepercentclub/bluebottle
697
+ summernote/django-summernote
698
+ zsiciarz/variablestars.net
699
+ manhhomienbienthuy/pythondotorg
700
+ Squareys/PyDDL
701
+ PatrikValkovic/grammpy
702
+ mitsuhiko/sentry
703
+ Clyde-fare/cclib_bak
704
+ andrewlin16/duckbot
705
+ weijia/djangoautoconf
706
+ BertrandBordage/django-terms
707
+ schwa-lab/dr-apps-python
708
+ ppb/ppb-vector
709
+ svetlyak40wt/python-cl-conditions
710
+ aman-iitj/scipy
711
+ MaxLikelihood/CODE
712
+ zhenzhai/edx-platform
713
+ lihui7115/ChromiumGStreamerBackend
714
+ cloudtools/troposphere
715
+ carsonmcdonald/glacier-cmd
716
+ gsnbng/erpnext
717
+ tm-kn/farmers-api
718
+ edx/ecommerce-api-client
719
+ DesertBus/txircd
720
+ e-mission/e-mission-server
721
+ wahuneke/django-stripe-payments
722
+ briansuhr/slowburn
723
+ GETLIMS/LIMS-Backend
724
+ robintw/scikit-image
725
+ it-projects-llc/website-addons
726
+ acgetchell/causal-sets-explorer
727
+ MarauderXtreme/sipa
728
+ CameronLonsdale/lantern
729
+ stan-dev/pystan
730
+ DigitalGlobe/gbdxtools
731
+ treyhunner/django-email-log
732
+ OCA/connector
733
+ open2c/cooltools
734
+ Schevo/kiwi
735
+ silas/rock
736
+ JohnVinyard/featureflow
737
+ umbc-hackafe/htcpcp
738
+ boluny/cray
739
+ DavidNorman/tensorflow
740
+ drougge/wwwwellpapp
741
+ Clinical-Genomics/scout
742
+ RNAcentral/rnacentral-webcode
743
+ ByteCommander/ChatExchange6
744
+ windmill/windmill
745
+ mcmontero/tinyAPI
746
+ jraede/dd-agent
747
+ WyohKnott/image-comparison-sources
748
+ jaraco/jaraco.logging
749
+ pgollakota/django-chartit
750
+ Frojd/wagtail-geo-widget
751
+ sunlightlabs/hanuman
752
+ jcarbaugh/django-wellknown
753
+ igordejanovic/parglare
754
+ iraquitan/udacity-fsnd-p4-conference-app
755
+ vintasoftware/django-role-permissions
756
+ j00bar/django-widgy
757
+ mayfield/cellulario
758
+ ghostwords/chameleon-crawler
759
+ YabinHu/miniflow
760
+ moyogo/fontbakery
761
+ chocopoche/mangopay2-python-sdk
762
+ jaraco/jaraco.classes
763
+ jitseniesen/spyder-memory-profiler
764
+ karan/TPB
765
+ shakib609/gitcloner
766
+ Daksh/sugar-toolkit-gtk3
767
+ weecology/mete-spatial
768
+ Secheron/compassion-switzerland
769
+ redice/graphite-web
770
+ DasIch/logbook
771
+ recklessromeo/otm-core
772
+ pabletos/Hubot-Warframe
773
+ nagareproject/core
774
+ fujita-shintaro/mkdocs
775
+ zsiciarz/pyaavso
776
+ openfisca/openfisca-tunisia
777
+ ISISComputingGroup/EPICS-inst_servers
778
+ emory-libraries/django-eultheme
779
+ hyperion-rt/hyperion
780
+ cardstack/cardstack
781
+ bltravis/django-alphabetfilter
782
+ zhangguiyu/django-hierarchical-auth
783
+ fmfi-svt-deadlock/hw-testing
784
+ spennihana/h2o-3
785
+ pastas/pasta
786
+ dkdndes/django-flatpages-example
787
+ p2pu/learning-circles
788
+ nikdoof/test-auth
789
+ vmalavolta/fabix
790
+ dtrip/.ubuntu
791
+ egenerat/flight-manager
792
+ robotenique/RandomAccessMemory
793
+ RDFLib/rdflib
794
+ pudo/storyweb
795
+ benjamindean/furi-kura
796
+ alphagov/ghtools
797
+ shad7/trakt.py
798
+ jaraco/hgtools
799
+ gbowerman/azurerm
800
+ sussman/zvm
memory_lora/codegraph.py ADDED
@@ -0,0 +1,221 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """AST-based codebase graph representation.
3
+
4
+ New data representation beyond what the Code2LoRA paper used (raw file
5
+ chunks, mean+max pooled). This module extracts a STRUCTURAL summary of a
6
+ Python codebase -- imports (dependency edges between files), class
7
+ hierarchies, function/method signatures, and a best-effort call graph --
8
+ and serializes it into compact text sections. Those sections are fed
9
+ through the SAME frozen embedding pipeline as raw code
10
+ (``memory_lora.encoder.embed_document`` already accepts a list of
11
+ ``(section_name, section_text)`` tuples), so a repository can be embedded
12
+ from BOTH its raw source text and its structural graph, without any
13
+ change to the encoder or hypernetwork.
14
+
15
+ Why this matters for "recall codebases": raw-text chunking captures
16
+ surface content (docstrings, comments, literal code) but dilutes the
17
+ signal that actually matters for API-level questions -- "what does
18
+ function X take", "what inherits from Y", "who imports Z". A compact
19
+ graph serialization puts that signal in a small number of dense tokens
20
+ instead of burying it across thousands of raw-code tokens.
21
+ """
22
+
23
+ from __future__ import annotations
24
+
25
+ import ast
26
+ from dataclasses import dataclass, field
27
+ from pathlib import Path
28
+ from typing import Dict, List, Optional, Tuple
29
+
30
+
31
+ @dataclass
32
+ class FunctionSig:
33
+ name: str
34
+ args: List[str]
35
+ returns: Optional[str]
36
+ is_method: bool = False
37
+ decorators: List[str] = field(default_factory=list)
38
+ calls: List[str] = field(default_factory=list) # best-effort, unresolved names
39
+
40
+
41
+ @dataclass
42
+ class ClassSig:
43
+ name: str
44
+ bases: List[str]
45
+ methods: List[FunctionSig] = field(default_factory=list)
46
+
47
+
48
+ @dataclass
49
+ class FileGraph:
50
+ path: str
51
+ imports: List[str]
52
+ import_froms: List[Tuple[str, List[str]]] # (module, [names])
53
+ classes: List[ClassSig]
54
+ functions: List[FunctionSig] # module-level only
55
+
56
+
57
+ def _annotation_to_str(node: Optional[ast.AST]) -> Optional[str]:
58
+ if node is None:
59
+ return None
60
+ try:
61
+ return ast.unparse(node)
62
+ except Exception: # noqa: BLE001
63
+ return None
64
+
65
+
66
+ def _arg_to_str(a: ast.arg) -> str:
67
+ ann = _annotation_to_str(a.annotation)
68
+ return f"{a.arg}: {ann}" if ann else a.arg
69
+
70
+
71
+ def _extract_calls(node: ast.AST) -> List[str]:
72
+ calls = []
73
+ for n in ast.walk(node):
74
+ if isinstance(n, ast.Call):
75
+ f = n.func
76
+ if isinstance(f, ast.Name):
77
+ calls.append(f.id)
78
+ elif isinstance(f, ast.Attribute):
79
+ calls.append(f.attr)
80
+ # dedupe, keep order
81
+ seen = set()
82
+ out = []
83
+ for c in calls:
84
+ if c not in seen:
85
+ seen.add(c)
86
+ out.append(c)
87
+ return out[:20] # cap -- this is a signal, not a full trace
88
+
89
+
90
+ def _function_sig(node, is_method: bool = False) -> FunctionSig:
91
+ args = [_arg_to_str(a) for a in node.args.args]
92
+ returns = _annotation_to_str(node.returns)
93
+ decorators = [_annotation_to_str(d) or "" for d in node.decorator_list]
94
+ return FunctionSig(
95
+ name=node.name, args=args, returns=returns, is_method=is_method,
96
+ decorators=[d for d in decorators if d], calls=_extract_calls(node),
97
+ )
98
+
99
+
100
+ def extract_file_graph(source: str, path: str) -> Optional[FileGraph]:
101
+ """Parse one Python file's source into a :class:`FileGraph`.
102
+ Returns None on a syntax error (skip the file, don't crash the repo)."""
103
+ try:
104
+ tree = ast.parse(source)
105
+ except (SyntaxError, ValueError):
106
+ return None
107
+
108
+ imports: List[str] = []
109
+ import_froms: List[Tuple[str, List[str]]] = []
110
+ classes: List[ClassSig] = []
111
+ functions: List[FunctionSig] = []
112
+
113
+ for node in ast.iter_child_nodes(tree):
114
+ if isinstance(node, ast.Import):
115
+ imports.extend(a.name for a in node.names)
116
+ elif isinstance(node, ast.ImportFrom):
117
+ mod = node.module or ("." * node.level)
118
+ import_froms.append((mod, [a.name for a in node.names]))
119
+ elif isinstance(node, ast.ClassDef):
120
+ bases = [_annotation_to_str(b) or "?" for b in node.bases]
121
+ methods = [
122
+ _function_sig(n, is_method=True)
123
+ for n in node.body
124
+ if isinstance(n, (ast.FunctionDef, ast.AsyncFunctionDef))
125
+ ]
126
+ classes.append(ClassSig(name=node.name, bases=bases, methods=methods))
127
+ elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
128
+ functions.append(_function_sig(node, is_method=False))
129
+
130
+ return FileGraph(path=path, imports=imports, import_froms=import_froms,
131
+ classes=classes, functions=functions)
132
+
133
+
134
+ def serialize_file_graph(g: FileGraph) -> str:
135
+ """Compact text serialization -- dense signature summary, not prose."""
136
+ lines = [f"# {g.path}"]
137
+ if g.imports:
138
+ lines.append("imports: " + ", ".join(g.imports))
139
+ for mod, names in g.import_froms:
140
+ lines.append(f"from {mod} import " + ", ".join(names))
141
+ for c in g.classes:
142
+ base_str = f"({', '.join(c.bases)})" if c.bases else ""
143
+ lines.append(f"class {c.name}{base_str}:")
144
+ for m in c.methods:
145
+ dec = "".join(f"@{d} " for d in m.decorators)
146
+ args = ", ".join(m.args)
147
+ ret = f" -> {m.returns}" if m.returns else ""
148
+ calls = f" # calls: {', '.join(m.calls[:6])}" if m.calls else ""
149
+ lines.append(f" {dec}def {m.name}({args}){ret}{calls}")
150
+ for fn in g.functions:
151
+ dec = "".join(f"@{d} " for d in fn.decorators)
152
+ args = ", ".join(fn.args)
153
+ ret = f" -> {fn.returns}" if fn.returns else ""
154
+ calls = f" # calls: {', '.join(fn.calls[:6])}" if fn.calls else ""
155
+ lines.append(f"{dec}def {fn.name}({args}){ret}{calls}")
156
+ return "\n".join(lines)
157
+
158
+
159
+ def extract_repo_graph_sections(
160
+ repo_dir: Path, max_files: int = 200, skip_dirs: Optional[set] = None,
161
+ ) -> List[Tuple[str, str]]:
162
+ """Walk a repo, extract + serialize each .py file's structural graph.
163
+ Returns ``[(section_name, section_text), ...]`` -- directly usable as
164
+ the ``sections`` argument to ``memory_lora.encoder.embed_document``,
165
+ alongside (or instead of) raw-text sections.
166
+ """
167
+ skip_dirs = skip_dirs or {".git", "__pycache__", ".venv", "venv", "node_modules",
168
+ "build", "dist", ".tox", ".mypy_cache"}
169
+ sections: List[Tuple[str, str]] = []
170
+ n = 0
171
+ for path in sorted(repo_dir.rglob("*.py")):
172
+ if any(part in skip_dirs for part in path.parts):
173
+ continue
174
+ try:
175
+ source = path.read_text(encoding="utf-8", errors="ignore")
176
+ except OSError:
177
+ continue
178
+ rel = str(path.relative_to(repo_dir))
179
+ g = extract_file_graph(source, rel)
180
+ if g is None:
181
+ continue
182
+ if not (g.imports or g.import_froms or g.classes or g.functions):
183
+ continue # empty file, no structural signal
184
+ sections.append((f"graph:{rel}", serialize_file_graph(g)))
185
+ n += 1
186
+ if n >= max_files:
187
+ break
188
+ return sections
189
+
190
+
191
+ def extract_repo_dependency_summary(repo_dir: Path, skip_dirs: Optional[set] = None) -> str:
192
+ """One dense paragraph: which files import which other in-repo modules.
193
+ A cheap approximation of a dependency graph edge list, useful as a
194
+ single extra section capturing repo-wide (not per-file) structure."""
195
+ skip_dirs = skip_dirs or {".git", "__pycache__", ".venv", "venv", "node_modules"}
196
+ edges: List[str] = []
197
+ module_names = set()
198
+ files = [p for p in repo_dir.rglob("*.py") if not any(part in skip_dirs for part in p.parts)]
199
+ for p in files:
200
+ mod = str(p.relative_to(repo_dir)).replace("/", ".").removesuffix(".py")
201
+ module_names.add(mod)
202
+
203
+ for p in files:
204
+ try:
205
+ source = p.read_text(encoding="utf-8", errors="ignore")
206
+ tree = ast.parse(source)
207
+ except (SyntaxError, ValueError, OSError):
208
+ continue
209
+ rel = str(p.relative_to(repo_dir))
210
+ for node in ast.walk(tree):
211
+ if isinstance(node, ast.ImportFrom) and node.module:
212
+ if node.module in module_names or any(m.startswith(node.module + ".") for m in module_names):
213
+ edges.append(f"{rel} -> {node.module}")
214
+ return "dependency edges:\n" + "\n".join(edges[:300]) if edges else ""
215
+
216
+
217
+ __all__ = [
218
+ "FunctionSig", "ClassSig", "FileGraph",
219
+ "extract_file_graph", "serialize_file_graph",
220
+ "extract_repo_graph_sections", "extract_repo_dependency_summary",
221
+ ]
memory_lora/core.py ADDED
@@ -0,0 +1,434 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Shared building blocks for the Memory-LoRA hypernetwork.
3
+
4
+ Forked from Code2LoRA's ``hypernetwork/code2lora_core.py`` (Hotsko et al.,
5
+ "Code2LoRA: Hypernetwork-Generated Adapters for Code Language Models under
6
+ Software Evolution", MIT-licensed code release). Same core trick, different
7
+ target model and conditioning input:
8
+
9
+ * Code2LoRA: repository embedding -> LoRA adapter for Qwen2.5-Coder-1.5B
10
+ * Memory-LoRA: document embedding -> LoRA adapter for google/gemma-4-E2B
11
+
12
+ The ``MemoryLoRAHead`` (renamed from ``Code2LoRAHead``, architecture
13
+ unchanged) outputs ONE (A, B) pair per LoRA module *type* (q_proj, k_proj,
14
+ v_proj, o_proj, gate_proj, up_proj, down_proj), shared across every target
15
+ transformer layer -- not per-layer. This keeps the head's parameter count
16
+ tractable for local (MPS) training.
17
+
18
+ Gemma-4-E2B specifics (verified against the model's actual safetensors
19
+ header, not guessed):
20
+
21
+ * Decoder is nested at ``model.language_model.layers.{i}.*`` -- NOT
22
+ ``model.layers.{i}.*`` like Qwen2.5-Coder. ``get_module_specs`` below
23
+ matches on ``language_model\\.layers\\.(\\d+)\\.``, not ``model\\.layers``.
24
+ * Module type names are identical to Code2LoRA's defaults:
25
+ q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj.
26
+ * Only ``model.language_model.*`` is ever touched. ``vision_tower`` and
27
+ ``audio_tower`` are left completely alone -- irrelevant to text recall and
28
+ risky to perturb.
29
+ """
30
+
31
+ from __future__ import annotations
32
+
33
+ import math
34
+ import re
35
+ from dataclasses import dataclass
36
+ from pathlib import Path
37
+ from typing import Any, Dict, List, Optional, Tuple
38
+
39
+ import numpy as np
40
+ import pyarrow as pa
41
+ import pyarrow.compute as pc
42
+ import pyarrow.dataset as pads
43
+ import torch
44
+ import torch.nn as nn
45
+ import torch.nn.functional as F
46
+
47
+
48
+ # ---------------------------------------------------------------------------
49
+ # LoRA module + injection (unchanged from Code2LoRA -- architecture-agnostic)
50
+ # ---------------------------------------------------------------------------
51
+
52
+ class LoRA(nn.Module):
53
+ """Wraps an ``nn.Linear`` with an additive low-rank update.
54
+
55
+ Forward: ``y = base(x) + scaling * (x @ A^T) @ B^T``, where per-batch
56
+ A: ``[rank, in_features]`` and B: ``[out_features, rank]`` come from an
57
+ external hypernet via :meth:`set_lora_weights`.
58
+
59
+ IMPORTANT autograd contract: A and B are kept as **plain attributes**,
60
+ not buffers, and stored **without detaching**, so the LM loss's backward
61
+ graph flows through them straight into the hypernet parameters that
62
+ produced them. The base ``nn.Linear`` is frozen and its forward sees a
63
+ detached copy of the input to avoid building an autograd graph through
64
+ the (much larger) frozen LLM weights.
65
+ """
66
+
67
+ def __init__(self, base: nn.Linear, in_features: int, out_features: int,
68
+ rank: int, alpha: float):
69
+ super().__init__()
70
+ self.base = base
71
+ for p in self.base.parameters():
72
+ p.requires_grad = False
73
+ self.in_features = in_features
74
+ self.out_features = out_features
75
+ self.rank = rank
76
+ self.scaling = float(alpha) / float(max(1, rank))
77
+ self.A: Optional[torch.Tensor] = None # [rank, in_features]
78
+ self.B: Optional[torch.Tensor] = None # [out_features, rank]
79
+
80
+ def set_lora_weights(self, A: torch.Tensor, B: torch.Tensor) -> None:
81
+ self.A = A
82
+ self.B = B
83
+
84
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
85
+ y = self.base(x)
86
+ if self.A is None or self.B is None:
87
+ return y
88
+ x_f32 = x.detach().to(torch.float32)
89
+ A = self.A.to(torch.float32)
90
+ B = self.B.to(torch.float32)
91
+ delta = F.linear(F.linear(x_f32, A), B) * self.scaling
92
+ return y + delta.to(dtype=y.dtype)
93
+
94
+
95
+ @dataclass
96
+ class ModuleSpec:
97
+ full_name: str # e.g. 'model.language_model.layers.5.self_attn.q_proj'
98
+ layer_idx: int
99
+ type: str # e.g. 'q_proj'
100
+ in_features: int
101
+ out_features: int
102
+
103
+
104
+ # Gemma-4-E2B nests its text decoder here (verified via safetensors header).
105
+ DEFAULT_ROOT_PREFIX = "model.language_model."
106
+ _LAYER_IDX_RE = re.compile(r"\blanguage_model\.layers\.(\d+)\.")
107
+
108
+
109
+ def get_module_specs(model: nn.Module, target_module_types: List[str],
110
+ root_prefix: str = DEFAULT_ROOT_PREFIX
111
+ ) -> List[ModuleSpec]:
112
+ """Discover every nn.Linear under ``root_prefix`` whose name contains one
113
+ of ``target_module_types`` and return one :class:`ModuleSpec` per match,
114
+ sorted by (layer_idx, full_name).
115
+
116
+ Restricting to ``root_prefix`` is what keeps ``vision_tower`` /
117
+ ``audio_tower`` untouched even though they also contain q_proj/k_proj/
118
+ v_proj/o_proj-named linears.
119
+
120
+ Gemma-4-E2B is architecturally heterogeneous across layers (unlike
121
+ Qwen2.5-Coder, which Code2LoRA was built for): every 5th layer is a
122
+ wider "full_attention" layer (q_proj/o_proj 2x the width of the
123
+ "sliding_attention" layers), and 20 of the 35 layers have NO k_proj/
124
+ v_proj at all -- they reuse an earlier layer's KV cache
125
+ (``num_kv_shared_layers=20`` in the model config). A LoRA (A, B) pair
126
+ can only be shared across modules of IDENTICAL shape, so ``.type`` here
127
+ is ``"{module_name}_{in}x{out}"`` (shape-qualified), not just the raw
128
+ module name -- e.g. ``"q_proj_1536x2048"`` vs ``"q_proj_1536x4096"``
129
+ end up as distinct hypernetwork output heads. Layers with no matching
130
+ module (e.g. k_proj on a KV-shared layer) simply produce no spec for
131
+ that layer, which is architecturally correct: there is nothing to
132
+ adapt there since that layer never computes its own K/V.
133
+ """
134
+ specs: List[ModuleSpec] = []
135
+ for name, m in model.named_modules():
136
+ if root_prefix and not name.startswith(root_prefix):
137
+ continue
138
+ match_type = next(
139
+ (t for t in target_module_types if t in name), None
140
+ )
141
+ if match_type is None:
142
+ continue
143
+ if not isinstance(m, nn.Linear):
144
+ continue
145
+ m_layer = _LAYER_IDX_RE.search(name)
146
+ layer_idx = int(m_layer.group(1)) if m_layer else -1
147
+ shape_qualified_type = f"{match_type}_{m.in_features}x{m.out_features}"
148
+ specs.append(ModuleSpec(
149
+ full_name=name,
150
+ layer_idx=layer_idx,
151
+ type=shape_qualified_type,
152
+ in_features=int(m.in_features),
153
+ out_features=int(m.out_features),
154
+ ))
155
+ specs.sort(key=lambda s: (s.layer_idx, s.full_name))
156
+ return specs
157
+
158
+
159
+ def replace_with_lora(model: nn.Module, specs: List[ModuleSpec],
160
+ rank: int, alpha: float) -> None:
161
+ """Replace each target ``nn.Linear`` in ``model`` with a :class:`LoRA`
162
+ wrapper. Idempotent."""
163
+ named = dict(model.named_modules())
164
+ device = next(model.parameters()).device
165
+ dtype = next(model.parameters()).dtype
166
+ for sp in specs:
167
+ parent_name, attr = sp.full_name.rsplit(".", 1)
168
+ orig = getattr(named[parent_name], attr)
169
+ if isinstance(orig, LoRA):
170
+ continue
171
+ assert isinstance(orig, nn.Linear), \
172
+ f"{sp.full_name} is not nn.Linear (got {type(orig)})"
173
+ wrapped = LoRA(orig, sp.in_features, sp.out_features,
174
+ rank, alpha).to(device=device, dtype=dtype)
175
+ setattr(named[parent_name], attr, wrapped)
176
+
177
+
178
+ def inject_lora_weights(model: nn.Module, specs: List[ModuleSpec],
179
+ head_out: Dict[str, Dict[str, torch.Tensor]],
180
+ batch_index: int = 0) -> None:
181
+ """Push ``head_out["A"][type]`` and ``head_out["B"][type]`` into the
182
+ wrapper :class:`LoRA` modules for every spec sharing that type."""
183
+ A_by_type = head_out["A"]
184
+ B_by_type = head_out["B"]
185
+ named = dict(model.named_modules())
186
+ for sp in specs:
187
+ named[sp.full_name].set_lora_weights(
188
+ A_by_type[sp.type][batch_index],
189
+ B_by_type[sp.type][batch_index],
190
+ )
191
+
192
+
193
+ def discover_module_types_and_dims(specs: List[ModuleSpec]
194
+ ) -> Dict[str, Tuple[int, int]]:
195
+ """Return {type_name: (in_features, out_features)} -- one entry per
196
+ target module type. Assumes all instances of the same type share dims."""
197
+ type_dims: Dict[str, Tuple[int, int]] = {}
198
+ for sp in specs:
199
+ if sp.type in type_dims:
200
+ assert type_dims[sp.type] == (sp.in_features, sp.out_features), \
201
+ f"type {sp.type} appears with inconsistent dims"
202
+ continue
203
+ type_dims[sp.type] = (sp.in_features, sp.out_features)
204
+ return type_dims
205
+
206
+
207
+ # ---------------------------------------------------------------------------
208
+ # Shared LoRA generation head (= Code2LoRAHead, renamed; architecture unchanged)
209
+ # ---------------------------------------------------------------------------
210
+
211
+ class MemoryLoRAHead(nn.Module):
212
+ """Maps a document-context embedding to a LoRA adapter in one forward
213
+ pass.
214
+
215
+ Input : ctx ``[B, input_dim]`` -- a single document embedding.
216
+ Output : ``{"A": {type: [B, rank, in_f]}, "B": {type: [B, out_f, rank]}}``,
217
+ one (A, B) pair per LoRA module *type*, shared across all
218
+ target transformer layers.
219
+
220
+ Args:
221
+ input_dim : Context-vector dim (2048, matches the Qwen3-Embedding
222
+ weighted-mean + max-pool concat from ``encoder.py``).
223
+ type_dims : ``{type: (in_features, out_features)}`` for each LoRA
224
+ module type (q_proj, v_proj, gate_proj, ...).
225
+ hidden_dim : Trunk hidden dimension. Default 128 -- deliberately
226
+ small: with only ~165 training documents (~3K QA
227
+ pairs), a 745M-param head (hidden_dim=512, the
228
+ original default) overfits within ~2 epochs (train
229
+ loss -> 0.4 while held-out cr_val/cr_test loss rises
230
+ from ~1.9 to ~2.7). hidden_dim=128 cuts head size
231
+ roughly 4x; combine with --head-dropout and higher
232
+ weight decay for further regularization.
233
+ rank : LoRA rank ``r``.
234
+ init_log_scale : Initial log-scale for tanh squashing. -3.5 gives
235
+ output magnitudes ~0.03 at init -> tiny LoRA delta.
236
+ dropout : Dropout applied after each trunk GELU. 0.0 (paper's
237
+ original setting) had no regularization at all;
238
+ nonzero here specifically to counter the overfitting
239
+ observed on this project's much smaller corpus.
240
+ """
241
+
242
+ def __init__(
243
+ self,
244
+ input_dim: int,
245
+ type_dims: Dict[str, Tuple[int, int]],
246
+ hidden_dim: int = 128,
247
+ rank: int = 16,
248
+ init_log_scale: float = -3.5,
249
+ dropout: float = 0.1,
250
+ ):
251
+ super().__init__()
252
+ self.input_dim = input_dim
253
+ self.hidden_dim = hidden_dim
254
+ self.rank = rank
255
+ self.dropout = dropout
256
+ self.type_dims = dict(type_dims)
257
+ self.types = sorted(type_dims.keys())
258
+
259
+ self.trunk = nn.Sequential(
260
+ nn.Linear(input_dim, hidden_dim),
261
+ nn.GELU(),
262
+ nn.Dropout(dropout),
263
+ nn.Linear(hidden_dim, hidden_dim),
264
+ nn.GELU(),
265
+ nn.Dropout(dropout),
266
+ )
267
+
268
+ self.heads_A = nn.ModuleDict({
269
+ t: nn.Linear(hidden_dim, rank * type_dims[t][0])
270
+ for t in self.types
271
+ })
272
+ self.heads_B = nn.ModuleDict({
273
+ t: nn.Linear(hidden_dim, type_dims[t][1] * rank)
274
+ for t in self.types
275
+ })
276
+ self.log_scale_A = nn.ParameterDict({
277
+ t: nn.Parameter(torch.tensor(init_log_scale)) for t in self.types
278
+ })
279
+ self.log_scale_B = nn.ParameterDict({
280
+ t: nn.Parameter(torch.tensor(init_log_scale)) for t in self.types
281
+ })
282
+
283
+ def forward(self, ctx: torch.Tensor) -> Dict[str, Dict[str, torch.Tensor]]:
284
+ if ctx.dim() == 3:
285
+ ctx = torch.max(ctx, dim=1).values
286
+ h = self.trunk(ctx.float())
287
+ h = F.normalize(h, p=2, dim=-1) * math.sqrt(self.hidden_dim)
288
+
289
+ A_out: Dict[str, torch.Tensor] = {}
290
+ B_out: Dict[str, torch.Tensor] = {}
291
+ for t in self.types:
292
+ in_f, out_f = self.type_dims[t]
293
+ A_raw = self.heads_A[t](h).view(-1, self.rank, in_f)
294
+ B_raw = self.heads_B[t](h).view(-1, out_f, self.rank)
295
+ scale_A = torch.exp(self.log_scale_A[t]).clamp(1e-5, 0.3)
296
+ scale_B = torch.exp(self.log_scale_B[t]).clamp(1e-5, 0.3)
297
+ A_out[t] = torch.tanh(A_raw) * scale_A
298
+ B_out[t] = torch.tanh(B_raw) * scale_B
299
+ return {"A": A_out, "B": B_out}
300
+
301
+ def config_dict(self) -> Dict[str, Any]:
302
+ return {
303
+ "input_dim": self.input_dim,
304
+ "hidden_dim": self.hidden_dim,
305
+ "rank": self.rank,
306
+ "dropout": self.dropout,
307
+ "types": self.types,
308
+ "type_dims": {t: list(v) for t, v in self.type_dims.items()},
309
+ }
310
+
311
+
312
+ # ---------------------------------------------------------------------------
313
+ # Parquet loaders -- documents + recall QA pairs
314
+ # ---------------------------------------------------------------------------
315
+
316
+ def _list_to_f32_array(col, dim: int) -> np.ndarray:
317
+ """Vectorized fixed-width-list -> ndarray. The naive per-row Python
318
+ loop (``for i, v in enumerate(col.to_pylist()): out[i] = v``) does
319
+ dim * n_rows individual scalar assignments in pure Python -- fine at
320
+ ~200 rows, but at real-corpus scale (74K rows x 2048 dims = 151M
321
+ scalar ops) it single-handedly took 5+ minutes just to load
322
+ embeddings before training could even start. pyarrow's own flatten()
323
+ + numpy reshape does the same conversion in C.
324
+ """
325
+ if len(col) == 0:
326
+ return np.zeros((0, dim), dtype=np.float32)
327
+ flat = col.combine_chunks().flatten() if hasattr(col, "combine_chunks") else col.flatten()
328
+ arr = flat.to_numpy(zero_copy_only=False).astype(np.float32, copy=False)
329
+ return arr.reshape(len(col), dim)
330
+
331
+
332
+ @dataclass
333
+ class DocRow:
334
+ doc_id: str
335
+ doc_version: str # constant "v1" for static (non-evolving) docs
336
+ split: str # "train" | "cr_val" | "cr_test" (cross-corpus)
337
+ doc_embedding: np.ndarray # fp32 [2048]
338
+
339
+
340
+ @dataclass
341
+ class QnaRow:
342
+ doc_id: str
343
+ doc_version: str
344
+ split: str # cross-corpus split, inherited from DocRow
345
+ qna_split: str # "train" | "held_out" (in-corpus split)
346
+ question: str
347
+ prefix: str
348
+ target: str
349
+
350
+
351
+ def load_doc_rows(parquet_path: Path,
352
+ splits: Optional[List[str]] = None,
353
+ embedding_col: str = "doc_embedding",
354
+ ) -> List[DocRow]:
355
+ needed = ["doc_id", "doc_version", "split", embedding_col]
356
+ ds = pads.dataset(str(parquet_path), format="parquet")
357
+ flt = None
358
+ if splits:
359
+ flt = pc.is_in(pads.field("split"),
360
+ value_set=pa.array(splits, type=pa.string()))
361
+ table = ds.to_table(columns=needed, filter=flt)
362
+ n = table.num_rows
363
+ if n == 0:
364
+ return []
365
+ dim = len(table.column(embedding_col)[0].as_py())
366
+ embs = _list_to_f32_array(table.column(embedding_col), dim)
367
+ doc_col = table.column("doc_id").to_pylist()
368
+ ver_col = table.column("doc_version").to_pylist()
369
+ split_col = table.column("split").to_pylist()
370
+ rows: List[DocRow] = []
371
+ for i in range(n):
372
+ rows.append(DocRow(
373
+ doc_id=doc_col[i], doc_version=ver_col[i],
374
+ split=split_col[i] or "",
375
+ doc_embedding=embs[i],
376
+ ))
377
+ return rows
378
+
379
+
380
+ def load_qna_rows(jsonl_path: Path,
381
+ splits: Optional[List[str]] = None,
382
+ qna_splits: Optional[List[str]] = None,
383
+ doc_ids: Optional[List[str]] = None,
384
+ ) -> List[QnaRow]:
385
+ """QnA pairs are written as JSONL by ``generate_synthetic_dataset.py``
386
+ (one row per line, cheap to append incrementally during generation) --
387
+ unlike doc embeddings, which are batch-written parquet. Filters are
388
+ applied in Python; at the scale of this project (low thousands of rows)
389
+ that's simpler and fast enough."""
390
+ import json as _json
391
+
392
+ splits_set = set(splits) if splits else None
393
+ qna_splits_set = set(qna_splits) if qna_splits else None
394
+ doc_ids_set = set(doc_ids) if doc_ids else None
395
+
396
+ rows: List[QnaRow] = []
397
+ with open(jsonl_path) as f:
398
+ for line in f:
399
+ line = line.strip()
400
+ if not line:
401
+ continue
402
+ d = _json.loads(line)
403
+ if splits_set and d.get("split") not in splits_set:
404
+ continue
405
+ if qna_splits_set and d.get("qna_split") not in qna_splits_set:
406
+ continue
407
+ if doc_ids_set and d.get("doc_id") not in doc_ids_set:
408
+ continue
409
+ rows.append(QnaRow(
410
+ doc_id=d.get("doc_id", ""),
411
+ doc_version=d.get("doc_version", "v1"),
412
+ split=d.get("split", ""),
413
+ qna_split=d.get("qna_split", ""),
414
+ question=d.get("question", ""),
415
+ prefix=d.get("prefix", ""),
416
+ target=d.get("target", ""),
417
+ ))
418
+ return rows
419
+
420
+
421
+ __all__ = [
422
+ "LoRA",
423
+ "ModuleSpec",
424
+ "DEFAULT_ROOT_PREFIX",
425
+ "get_module_specs",
426
+ "replace_with_lora",
427
+ "inject_lora_weights",
428
+ "discover_module_types_and_dims",
429
+ "MemoryLoRAHead",
430
+ "DocRow",
431
+ "QnaRow",
432
+ "load_doc_rows",
433
+ "load_qna_rows",
434
+ ]
memory_lora/data_paths.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Local data path resolution for Memory-LoRA.
3
+
4
+ Unlike Code2LoRA's ``data_paths.py`` (which lazily ``snapshot_download``s from
5
+ the ``code2lora/`` HF org), everything here is generated locally via
6
+ OpenRouter and never leaves the machine unless the user chooses to publish
7
+ it -- so this just resolves to ``<repo_root>/data/``.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from pathlib import Path
13
+
14
+ REPO_ROOT = Path(__file__).resolve().parent.parent
15
+ DATA_ROOT = REPO_ROOT / "data"
16
+
17
+ DOCS_DIR = DATA_ROOT / "docs" # raw generated documents (jsonl)
18
+ EMBEDDINGS_DIR = DATA_ROOT / "embeddings" # doc embeddings parquet
19
+ QNA_DIR = DATA_ROOT / "qna" # recall QA pairs parquet
20
+ CACHE_DIR = DATA_ROOT / "openrouter_cache" # raw OpenRouter responses, keyed by prompt hash
21
+ RUNS_DIR = REPO_ROOT / "runs" # training checkpoints + metrics
22
+
23
+
24
+ def ensure_dirs() -> None:
25
+ for d in (DOCS_DIR, EMBEDDINGS_DIR, QNA_DIR, CACHE_DIR, RUNS_DIR):
26
+ d.mkdir(parents=True, exist_ok=True)
27
+
28
+
29
+ __all__ = [
30
+ "REPO_ROOT", "DATA_ROOT", "DOCS_DIR", "EMBEDDINGS_DIR", "QNA_DIR",
31
+ "CACHE_DIR", "RUNS_DIR", "ensure_dirs",
32
+ ]
memory_lora/encoder.py ADDED
@@ -0,0 +1,268 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Frozen document encoder for the Memory-LoRA hypernetwork.
3
+
4
+ Forked from Code2LoRA's ``create_dataset/embed_repos.py`` chunk/pool
5
+ pipeline (mean-pool chunks -> file vector -> weighted-mean+max repo vector),
6
+ retargeted from "repo files" to "document sections":
7
+
8
+ * Code2LoRA: file_i -> chunks -> mean-pool -> file vector
9
+ repo -> weighted-mean+max over file vectors
10
+ * Memory-LoRA: doc_section_i -> chunks -> mean-pool -> section vector
11
+ doc -> weighted-mean+max over section vectors
12
+
13
+ Same frozen encoder as the paper (Qwen3-Embedding-0.6B), same reasoning for
14
+ the weighting (content-distinctiveness via cosine-distance-from-mean +
15
+ log-size normalization) -- multi-section documents (e.g. the Code2LoRA paper
16
+ chunked into abstract/method/results/limitations) benefit from it exactly
17
+ the way multi-file repos did. Single-section synthetic fact-sheets degenerate
18
+ gracefully to a near-uniform weighting over their own chunks.
19
+
20
+ No gradient ever flows through this encoder; embeddings are precomputed once
21
+ and cached to parquet by ``scripts/build_doc_embeddings.py``.
22
+ """
23
+
24
+ from __future__ import annotations
25
+
26
+ import re
27
+ from typing import List, Optional, Tuple
28
+
29
+ import torch
30
+ import torch.nn.functional as F
31
+ from transformers import AutoModel, AutoTokenizer
32
+
33
+ DEFAULT_EMBED_MODEL = "Qwen/Qwen3-Embedding-0.6B"
34
+
35
+ # Section-name heuristics (loose analogue of Code2LoRA's path up/down-weight
36
+ # lists). Neutral by default for synthetic single-section documents; the
37
+ # upweighted names matter for the multi-section Code2LoRA-paper document.
38
+ SECTION_UPWEIGHT = [
39
+ r"abstract", r"result", r"conclusion", r"contribution",
40
+ ]
41
+ SECTION_DOWNWEIGHT = [
42
+ r"acknowledg", r"reference", r"appendix",
43
+ ]
44
+
45
+ MIN_CHARS_FOR_FULL_WEIGHT = 200 # sections shorter than this are downweighted
46
+
47
+
48
+ # ---------------------------------------------------------------------------
49
+ # Chunking
50
+ # ---------------------------------------------------------------------------
51
+
52
+ def chunk_token_ids(token_ids: List[int], chunk_tokens: int, overlap: int) -> List[List[int]]:
53
+ """Produce overlapping token windows (identical to Code2LoRA's version)."""
54
+ if chunk_tokens <= 0:
55
+ raise ValueError("chunk_tokens must be > 0")
56
+ if overlap >= chunk_tokens:
57
+ raise ValueError("chunk_overlap must be < chunk_tokens")
58
+ chunks: List[List[int]] = []
59
+ step = chunk_tokens - overlap
60
+ n = len(token_ids)
61
+ if n == 0:
62
+ return chunks
63
+ for start in range(0, n, step):
64
+ end = min(start + chunk_tokens, n)
65
+ window = token_ids[start:end]
66
+ if len(window) < 16:
67
+ continue
68
+ chunks.append(window)
69
+ if end >= n:
70
+ break
71
+ return chunks
72
+
73
+
74
+ # ---------------------------------------------------------------------------
75
+ # Embedding model wrapper
76
+ # ---------------------------------------------------------------------------
77
+
78
+ @torch.inference_mode()
79
+ def embed_texts(
80
+ model: AutoModel,
81
+ tokenizer: AutoTokenizer,
82
+ texts: List[str],
83
+ device: str,
84
+ batch_size: int,
85
+ max_length: int,
86
+ ) -> torch.Tensor:
87
+ """Return embeddings [N, D] using mean pooling over last_hidden_state."""
88
+ all_vecs = []
89
+ for i in range(0, len(texts), batch_size):
90
+ batch = texts[i:i + batch_size]
91
+ enc = tokenizer(
92
+ batch, padding=True, truncation=True,
93
+ max_length=max_length, return_tensors="pt",
94
+ )
95
+ enc = {k: v.to(device) for k, v in enc.items()}
96
+ out = model(**enc)
97
+ last = out.last_hidden_state # [B, T, H]
98
+ mask = enc["attention_mask"].unsqueeze(-1) # [B, T, 1]
99
+ mean = (last * mask).sum(dim=1) / mask.sum(dim=1).clamp(min=1)
100
+ all_vecs.append(mean.detach().cpu())
101
+ if not all_vecs:
102
+ return torch.empty((0, model.config.hidden_size))
103
+ return torch.cat(all_vecs, dim=0)
104
+
105
+
106
+ # ---------------------------------------------------------------------------
107
+ # Pooling: chunks -> section -> document
108
+ # ---------------------------------------------------------------------------
109
+
110
+ def pool_section_embeddings(chunk_embs: torch.Tensor) -> Optional[torch.Tensor]:
111
+ """chunk_embs [K, D] -> section_emb [D]"""
112
+ if chunk_embs.numel() == 0:
113
+ return None
114
+ return chunk_embs.mean(dim=0)
115
+
116
+
117
+ def _section_name_bonus(section_name: str) -> float:
118
+ s = section_name.lower()
119
+ bonus = 0.0
120
+ for pat in SECTION_DOWNWEIGHT:
121
+ if re.search(pat, s):
122
+ bonus -= 0.25
123
+ break
124
+ for pat in SECTION_UPWEIGHT:
125
+ if re.search(pat, s):
126
+ bonus += 0.15
127
+ break
128
+ return bonus
129
+
130
+
131
+ def compute_section_weights(
132
+ section_embs: torch.Tensor, # [S, D]
133
+ section_char_counts: torch.Tensor, # [S]
134
+ section_names: List[str],
135
+ a_distinct: float,
136
+ b_size: float,
137
+ tau: float,
138
+ ) -> torch.Tensor:
139
+ """
140
+ Whole-doc, all-sections weighting:
141
+ distinct_i = 1 - cos(s_i, mean_s)
142
+ size_i = normalized log(1+chars)
143
+ score_i = a_distinct * distinct_i + b_size * size_i + name_bonus_i + tiny_section_penalty
144
+ w = softmax(score / tau)
145
+ Returns: w [S] sum=1
146
+ """
147
+ f_norm = F.normalize(section_embs, p=2, dim=-1)
148
+ mean_f = F.normalize(f_norm.mean(dim=0, keepdim=True), p=2, dim=-1)
149
+ cos = (f_norm * mean_f).sum(dim=-1).clamp(-1, 1)
150
+ distinct = 1.0 - cos
151
+
152
+ chars = section_char_counts.float().clamp(min=1)
153
+ log_chars = torch.log1p(chars)
154
+ if log_chars.numel() > 1:
155
+ lo, hi = log_chars.min(), log_chars.max()
156
+ size01 = (log_chars - lo) / (hi - lo + 1e-8)
157
+ else:
158
+ size01 = torch.ones_like(log_chars)
159
+
160
+ name_bonus = torch.tensor([_section_name_bonus(n) for n in section_names],
161
+ dtype=torch.float32)
162
+ tiny_scale = (chars / float(MIN_CHARS_FOR_FULL_WEIGHT)).clamp(max=1.0)
163
+ tiny_bonus = torch.log(tiny_scale + 1e-6)
164
+
165
+ score = (a_distinct * distinct.cpu() + b_size * size01.cpu()
166
+ + name_bonus + 0.15 * tiny_bonus.cpu())
167
+ return torch.softmax(score / max(tau, 1e-6), dim=0)
168
+
169
+
170
+ def pool_doc_embedding_weighted(
171
+ section_embs: torch.Tensor, # [S, D]
172
+ section_char_counts: torch.Tensor, # [S]
173
+ section_names: List[str],
174
+ a_distinct: float = 1.0,
175
+ b_size: float = 0.5,
176
+ tau: float = 0.5,
177
+ alpha_mean: float = 1.0,
178
+ beta_max: float = 1.0,
179
+ ) -> Optional[torch.Tensor]:
180
+ """Aggregate section embeddings into one document vector:
181
+ concat(alpha_mean * weighted_mean, beta_max * max) -> [2D]. No final
182
+ L2 normalization (matches Code2LoRA's repo-vector convention)."""
183
+ if section_embs.numel() == 0:
184
+ return None
185
+ w = compute_section_weights(
186
+ section_embs, section_char_counts, section_names,
187
+ a_distinct, b_size, tau,
188
+ ).to(section_embs.dtype)
189
+ wmean = (section_embs * w.unsqueeze(-1)).sum(dim=0)
190
+ vmax = section_embs.max(dim=0).values
191
+ return torch.cat([alpha_mean * wmean, beta_max * vmax], dim=0)
192
+
193
+
194
+ # ---------------------------------------------------------------------------
195
+ # Main pipeline per document
196
+ # ---------------------------------------------------------------------------
197
+
198
+ def embed_document(
199
+ sections: List[Tuple[str, str]], # [(section_name, section_text), ...]
200
+ model: AutoModel,
201
+ tokenizer: AutoTokenizer,
202
+ device: str,
203
+ chunk_tokens: int = 4096,
204
+ chunk_overlap: int = 512,
205
+ batch_size: int = 4,
206
+ a_distinct: float = 1.0,
207
+ b_size: float = 0.5,
208
+ tau: float = 0.5,
209
+ alpha_mean: float = 1.0,
210
+ beta_max: float = 1.0,
211
+ ) -> Optional[torch.Tensor]:
212
+ """One document = list of (name, text) sections (single-element for a
213
+ plain synthetic fact-sheet; multi-element for the chunked paper).
214
+ Returns a [2D] embedding, or None if the document had no usable text."""
215
+ section_vectors: List[torch.Tensor] = []
216
+ section_names: List[str] = []
217
+ section_char_counts: List[int] = []
218
+
219
+ for name, text in sections:
220
+ text = (text or "").strip()
221
+ if not text:
222
+ continue
223
+ ids = tokenizer.encode(text, add_special_tokens=False)
224
+ windows = chunk_token_ids(ids, chunk_tokens=chunk_tokens, overlap=chunk_overlap)
225
+ if not windows:
226
+ continue
227
+ chunks = [tokenizer.decode(w, skip_special_tokens=True) for w in windows]
228
+ chunk_embs = embed_texts(
229
+ model=model, tokenizer=tokenizer, texts=chunks,
230
+ device=device, batch_size=batch_size, max_length=chunk_tokens,
231
+ )
232
+ svec = pool_section_embeddings(chunk_embs)
233
+ if svec is None:
234
+ continue
235
+ section_vectors.append(svec)
236
+ section_names.append(name)
237
+ section_char_counts.append(len(text))
238
+
239
+ if not section_vectors:
240
+ return None
241
+
242
+ section_embs = torch.stack(section_vectors, dim=0)
243
+ char_t = torch.tensor(section_char_counts, dtype=torch.int64)
244
+ return pool_doc_embedding_weighted(
245
+ section_embs, char_t, section_names,
246
+ a_distinct=a_distinct, b_size=b_size, tau=tau,
247
+ alpha_mean=alpha_mean, beta_max=beta_max,
248
+ )
249
+
250
+
251
+ def load_encoder(model_name: str = DEFAULT_EMBED_MODEL, device: str = "mps"):
252
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
253
+ model = AutoModel.from_pretrained(model_name, torch_dtype=torch.float32)
254
+ model.to(device)
255
+ model.eval()
256
+ return model, tokenizer
257
+
258
+
259
+ __all__ = [
260
+ "DEFAULT_EMBED_MODEL",
261
+ "chunk_token_ids",
262
+ "embed_texts",
263
+ "pool_section_embeddings",
264
+ "compute_section_weights",
265
+ "pool_doc_embedding_weighted",
266
+ "embed_document",
267
+ "load_encoder",
268
+ ]
requirements.txt ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Memory-LoRA for google/gemma-4-E2B -- local (MPS) requirements.
2
+ #
3
+ # transformers must be installed from the main/dev branch: as of writing,
4
+ # Gemma4ForConditionalGeneration (model_type "gemma4") is not yet in a
5
+ # pinned PyPI release (the model's own config.json requires
6
+ # transformers_version >= 5.5.0.dev0).
7
+ #
8
+ # pip install "git+https://github.com/huggingface/transformers.git"
9
+ #
10
+ # torch installs the MPS-enabled build automatically on macOS (no separate
11
+ # index-url needed for Apple Silicon).
12
+
13
+ torch==2.13.0
14
+ transformers @ git+https://github.com/huggingface/transformers.git
15
+ accelerate==1.14.0
16
+ numpy==2.5.1
17
+ pyarrow==25.0.0
18
+ tqdm==4.69.0
19
+ sentencepiece==0.2.2
20
+ protobuf==7.35.1
21
+ tensorboard==2.21.0
22
+ openai==2.48.0
runs/sixview_v1/head.best.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:42b3ca944c28284e7c391bb15347765cc183edad70f9fc01eca7d52b47d81fc9
3
+ size 754581207
runs/sixview_v1/head.latest.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:de50128411b62dbe548aa778de92946a5cb27d9c7ed6dd00fb0e04dbe3fddc9e
3
+ size 754581395
runs/sixview_v1/metrics.jsonl ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {"step": 200, "epoch": 0, "end_of_epoch": false, "eval_loss": 3.073296190737905, "suites": {"cr_val": {"eval_loss": 3.073296190737905, "n_docs": 40, "n_tokens": 6170}, "cr_test": {"eval_loss": 3.0465956268583674, "n_docs": 40, "n_tokens": 5901}, "ir_test": {"eval_loss": 3.2239975754518686, "n_docs": 25, "n_tokens": 805}}}
2
+ {"step": 400, "epoch": 0, "end_of_epoch": false, "eval_loss": 2.938264944642251, "suites": {"cr_val": {"eval_loss": 2.938264944642251, "n_docs": 40, "n_tokens": 6170}, "cr_test": {"eval_loss": 2.890953134488421, "n_docs": 40, "n_tokens": 5901}, "ir_test": {"eval_loss": 2.889070537964009, "n_docs": 25, "n_tokens": 805}}}
3
+ {"step": 415, "epoch": 0, "end_of_epoch": true, "eval_loss": 2.925391464855528, "suites": {"cr_val": {"eval_loss": 2.925391464855528, "n_docs": 40, "n_tokens": 6170}, "cr_test": {"eval_loss": 2.8815196507705547, "n_docs": 40, "n_tokens": 5901}, "ir_test": {"eval_loss": 2.8640587694156245, "n_docs": 25, "n_tokens": 805}}}
4
+ {"step": 600, "epoch": 1, "end_of_epoch": false, "eval_loss": 2.9148157247074997, "suites": {"cr_val": {"eval_loss": 2.9148157247074997, "n_docs": 40, "n_tokens": 6170}, "cr_test": {"eval_loss": 2.8689732771771497, "n_docs": 40, "n_tokens": 5901}, "ir_test": {"eval_loss": 2.7616432108494067, "n_docs": 25, "n_tokens": 805}}}
5
+ {"step": 800, "epoch": 1, "end_of_epoch": false, "eval_loss": 2.8480377581749394, "suites": {"cr_val": {"eval_loss": 2.8480377581749394, "n_docs": 40, "n_tokens": 6170}, "cr_test": {"eval_loss": 2.8288494332162752, "n_docs": 40, "n_tokens": 5901}, "ir_test": {"eval_loss": 2.6785004036026714, "n_docs": 25, "n_tokens": 805}}}
6
+ {"step": 830, "epoch": 1, "end_of_epoch": true, "eval_loss": 2.885955327256572, "suites": {"cr_val": {"eval_loss": 2.885955327256572, "n_docs": 40, "n_tokens": 6170}, "cr_test": {"eval_loss": 2.8312791101489303, "n_docs": 40, "n_tokens": 5901}, "ir_test": {"eval_loss": 2.668821378228087, "n_docs": 25, "n_tokens": 805}}}
7
+ {"step": 1000, "epoch": 2, "end_of_epoch": false, "eval_loss": 3.0374551723996475, "suites": {"cr_val": {"eval_loss": 3.0374551723996475, "n_docs": 40, "n_tokens": 6170}, "cr_test": {"eval_loss": 2.9976756136774148, "n_docs": 40, "n_tokens": 5901}, "ir_test": {"eval_loss": 2.6696533814720484, "n_docs": 25, "n_tokens": 805}}}
8
+ {"step": 1200, "epoch": 2, "end_of_epoch": false, "eval_loss": 3.0449040086767853, "suites": {"cr_val": {"eval_loss": 3.0449040086767853, "n_docs": 40, "n_tokens": 6170}, "cr_test": {"eval_loss": 3.0007799045652925, "n_docs": 40, "n_tokens": 5901}, "ir_test": {"eval_loss": 2.596094616525662, "n_docs": 25, "n_tokens": 805}}}
9
+ {"step": 1245, "epoch": 2, "end_of_epoch": true, "eval_loss": 3.019029198608677, "suites": {"cr_val": {"eval_loss": 3.019029198608677, "n_docs": 40, "n_tokens": 6170}, "cr_test": {"eval_loss": 2.9622069910368136, "n_docs": 40, "n_tokens": 5901}, "ir_test": {"eval_loss": 2.534812292623224, "n_docs": 25, "n_tokens": 805}}}
10
+ {"step": 1400, "epoch": 3, "end_of_epoch": false, "eval_loss": 3.3129004250276033, "suites": {"cr_val": {"eval_loss": 3.3129004250276033, "n_docs": 40, "n_tokens": 6170}, "cr_test": {"eval_loss": 3.2453028188683466, "n_docs": 40, "n_tokens": 5901}, "ir_test": {"eval_loss": 2.5926491863238885, "n_docs": 25, "n_tokens": 805}}}
11
+ {"step": 1600, "epoch": 3, "end_of_epoch": false, "eval_loss": 3.4394415961478866, "suites": {"cr_val": {"eval_loss": 3.4394415961478866, "n_docs": 40, "n_tokens": 6170}, "cr_test": {"eval_loss": 3.3522856792662634, "n_docs": 40, "n_tokens": 5901}, "ir_test": {"eval_loss": 2.655274886281594, "n_docs": 25, "n_tokens": 805}}}
runs/sixview_v1/tb/events.out.tfevents.1784911625.MAC-722851.16547.0 ADDED
Binary file (18.1 kB). View file
 
runs/sixview_v2/head.snapshot.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:38bf91d46b037d1df7f8827e6ab2a05b0e5d76f69b3bfd880b67d46fde06a8a6
3
+ size 754581395
runs/sixview_v2/head.t0030m.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:74cdb1549d14d59c18110ff7b9a50334158e7332e9dd118ae139bdd5e664086f
3
+ size 754581395
runs/sixview_v2/tb/events.out.tfevents.1784929857.MAC-722851.35539.0 ADDED
Binary file (2.08 kB). View file
 
scripts/assemble_6view_dataset.py ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Assemble the final ALIGNED 6-view training dataset by joining the
3
+ multi-view embeddings (inputs, doc_id = 'owner/repo') to ALL tech-lead QA
4
+ (targets) matched by repo name (commitpack/swe QA carry 'owner/repo@commit'
5
+ -> stripped to 'owner/repo'). This turns 132 repo-scoped-only aligned repos
6
+ into 515 aligned repos (~4000 QA) -- the best use of what we built.
7
+
8
+ Splits (per repo, deterministic): 80% train / 10% cr_val / 10% cr_test, so
9
+ the hypernetwork is evaluated on held-out repos it never trained on. Within
10
+ train repos, ~15% of QA -> qna_split=held_out (feeds ir_test).
11
+
12
+ Per-repo QA cap keeps any single repo (e.g. django) from dominating.
13
+
14
+ Output: data/embeddings/aligned6_embeddings.parquet
15
+ data/qna/aligned6_qna.jsonl
16
+ """
17
+ from __future__ import annotations
18
+ import json, hashlib, random, sys
19
+ from collections import defaultdict
20
+ from pathlib import Path
21
+ import pyarrow as pa, pyarrow.parquet as pq
22
+ HERE = Path(__file__).resolve().parent; REPO_ROOT = HERE.parent
23
+ sys.path.insert(0, str(REPO_ROOT))
24
+ from memory_lora.data_paths import EMBEDDINGS_DIR, QNA_DIR
25
+
26
+ PER_REPO_CAP = 20
27
+
28
+ def split_of(repo: str) -> str:
29
+ h = int(hashlib.md5(repo.encode()).hexdigest(), 16) % 100
30
+ if h < 10: return "cr_test"
31
+ if h < 20: return "cr_val"
32
+ return "train"
33
+
34
+ def main():
35
+ rng = random.Random(3407)
36
+ mv = pq.read_table(EMBEDDINGS_DIR / "multiview_embeddings.parquet").to_pylist()
37
+ mv_by_repo = {}
38
+ for r in mv: # dedupe by repo (keep first)
39
+ mv_by_repo.setdefault(r["doc_id"], r)
40
+ mv_repos = set(mv_by_repo)
41
+
42
+ qa_by_repo = defaultdict(list)
43
+ for f in ["repo_scoped_qa.jsonl", "techlead_qa_commitpack.jsonl", "techlead_qa.jsonl"]:
44
+ p = QNA_DIR / f
45
+ if not p.exists(): continue
46
+ for l in open(p):
47
+ d = json.loads(l); repo = d["doc_id"].split("@")[0]
48
+ if repo in mv_repos:
49
+ qa_by_repo[repo].append(d)
50
+
51
+ # embeddings with splits (only repos that have >=1 QA are trainable/evaluable)
52
+ emb_rows = []
53
+ for repo, r in mv_by_repo.items():
54
+ if repo not in qa_by_repo: continue
55
+ emb_rows.append({"doc_id": repo, "doc_version": "head", "split": split_of(repo),
56
+ "category": "aligned6", "doc_embedding": r["doc_embedding"]})
57
+ t = pa.table({k: [e[k] for e in emb_rows] for k in
58
+ ["doc_id", "doc_version", "split", "category", "doc_embedding"]})
59
+ pq.write_table(t, EMBEDDINGS_DIR / "aligned6_embeddings.parquet")
60
+
61
+ # qna with qna_split
62
+ n_qa = 0
63
+ from collections import Counter
64
+ split_ct = Counter()
65
+ with (QNA_DIR / "aligned6_qna.jsonl").open("w") as out:
66
+ for repo, rows in qa_by_repo.items():
67
+ sp = split_of(repo)
68
+ if len(rows) > PER_REPO_CAP:
69
+ rows = rng.sample(rows, PER_REPO_CAP)
70
+ for i, d in enumerate(rows):
71
+ if sp == "train":
72
+ qsplit = "held_out" if rng.random() < 0.15 else "train"
73
+ else:
74
+ qsplit = "held_out" # cr_val/cr_test: all held out
75
+ out.write(json.dumps({"doc_id": repo, "doc_version": "head",
76
+ "split": sp, "qna_split": qsplit, "aspect": d.get("aspect", "?"),
77
+ "question": d.get("question", ""), "prefix": d["prefix"],
78
+ "target": d["target"], "lang": d.get("lang", "unknown")}) + "\n")
79
+ n_qa += 1
80
+ split_ct[sp] += 1
81
+
82
+ print(f"aligned6 dataset: {len(emb_rows)} repos (embeddings) | {n_qa} QA")
83
+ print(f" repo splits: {Counter(split_of(r) for r in qa_by_repo)}")
84
+ print(f" QA by split: {dict(split_ct)}")
85
+ print(f" -> aligned6_embeddings.parquet + aligned6_qna.jsonl")
86
+
87
+ if __name__ == "__main__":
88
+ main()
scripts/augment_paraphrases.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Augment a document's QA pairs with paraphrased variants of the SAME facts.
3
+
4
+ Why: the direct-LoRA experiment on the Code2LoRA paper doc (runs/direct_paper)
5
+ converged to train_loss=0.0 but only hit 33% exact-match on its OWN training
6
+ questions at free-generation time, with several wrong answers collapsing to
7
+ the same recycled string (e.g. "47.4%" answering four different percentage
8
+ questions). With ~1 phrasing per fact and ~18 facts total, the model found a
9
+ shortcut (a few frequently-reinforced answers) instead of learning to
10
+ discriminate between questions. Multiple paraphrases of the SAME fact force
11
+ the model to actually condition on question content rather than pattern-
12
+ match a training-set shortcut.
13
+
14
+ This does NOT introduce new facts -- it takes the existing (question,
15
+ answer) pairs for a document and asks the model to rephrase the QUESTION
16
+ several different ways while keeping the answer identical.
17
+
18
+ Usage:
19
+ python scripts/augment_paraphrases.py --doc-id code2lora_paper --n-paraphrases 5
20
+ """
21
+
22
+ from __future__ import annotations
23
+
24
+ import argparse
25
+ import json
26
+ import os
27
+ import re
28
+ import sys
29
+ from pathlib import Path
30
+ from typing import List
31
+
32
+ from openai import OpenAI
33
+
34
+ HERE = Path(__file__).resolve().parent
35
+ REPO_ROOT = HERE.parent
36
+ sys.path.insert(0, str(REPO_ROOT))
37
+ from memory_lora.data_paths import QNA_DIR, CACHE_DIR, ensure_dirs # noqa: E402
38
+ from generate_synthetic_dataset import ( # noqa: E402
39
+ CachedClient, _load_dotenv, DEFAULT_GEN_MODEL, OPENROUTER_BASE_URL,
40
+ )
41
+
42
+ _load_dotenv(REPO_ROOT / ".env")
43
+
44
+ PARAPHRASE_SYSTEM = (
45
+ "You rewrite a factual question in N different ways while keeping its "
46
+ "meaning and the correct short answer completely unchanged. Output a "
47
+ "JSON array of N strings, each a differently-phrased question that "
48
+ "still has the exact same answer as the original. Vary sentence "
49
+ "structure, word choice, and question format (e.g. direct question, "
50
+ "'what value/number', fill-in-the-blank style) -- but never change what "
51
+ "is being asked. Output ONLY the JSON array, no prose."
52
+ )
53
+
54
+
55
+ def gen_paraphrases(client: CachedClient, model: str, question: str, answer: str, n: int) -> List[str]:
56
+ prompt = f"Original question: {question}\nCorrect answer: {answer.strip()}\nGenerate {n} paraphrases."
57
+ raw = client.chat(
58
+ model=model,
59
+ messages=[
60
+ {"role": "system", "content": PARAPHRASE_SYSTEM},
61
+ {"role": "user", "content": prompt},
62
+ ],
63
+ temperature=0.8,
64
+ max_tokens=800,
65
+ )
66
+ match = re.search(r"\[.*\]", raw, re.DOTALL)
67
+ if not match:
68
+ return []
69
+ try:
70
+ items = json.loads(match.group(0))
71
+ except json.JSONDecodeError:
72
+ return []
73
+ return [q.strip() for q in items if isinstance(q, str) and q.strip()]
74
+
75
+
76
+ def main() -> None:
77
+ ap = argparse.ArgumentParser()
78
+ ap.add_argument("--doc-id", required=True)
79
+ ap.add_argument("--n-paraphrases", type=int, default=5)
80
+ ap.add_argument("--gen-model", default=DEFAULT_GEN_MODEL)
81
+ ap.add_argument("--held-out-fraction", type=float, default=0.15,
82
+ help="Fraction of NEW paraphrases assigned to "
83
+ "qna_split=held_out (rest go to train, since the "
84
+ "goal here is more train-time exposure per fact).")
85
+ args = ap.parse_args()
86
+
87
+ ensure_dirs()
88
+ api_key = os.environ.get("OPENROUTER_API_KEY")
89
+ if not api_key:
90
+ raise SystemExit("OPENROUTER_API_KEY not set (expected in .env)")
91
+ client = CachedClient(OpenAI(base_url=OPENROUTER_BASE_URL, api_key=api_key), cache_dir=CACHE_DIR)
92
+
93
+ qna_path = QNA_DIR / "qna.jsonl"
94
+ rows = [json.loads(l) for l in qna_path.open()]
95
+ doc_rows = [r for r in rows if r["doc_id"] == args.doc_id and r["qna_split"] == "train"]
96
+ print(f"Found {len(doc_rows)} existing train QA pairs for {args.doc_id}", flush=True)
97
+
98
+ import random
99
+ rng = random.Random(3407)
100
+ new_rows = []
101
+ for r in doc_rows:
102
+ question = r["question"] if r.get("question") else r["prefix"].removeprefix("Q: ").removesuffix("\nA:")
103
+ paraphrases = gen_paraphrases(client, args.gen_model, question, r["target"], args.n_paraphrases)
104
+ for pq in paraphrases:
105
+ qna_split = "held_out" if rng.random() < args.held_out_fraction else "train"
106
+ new_rows.append({
107
+ "doc_id": r["doc_id"], "doc_version": r["doc_version"], "split": r["split"],
108
+ "qna_split": qna_split, "question": pq,
109
+ "prefix": f"Q: {pq}\nA:", "target": r["target"],
110
+ })
111
+ print(f" {question[:60]!r} -> {len(paraphrases)} paraphrases", flush=True)
112
+
113
+ with qna_path.open("a") as f:
114
+ for row in new_rows:
115
+ f.write(json.dumps(row) + "\n")
116
+ print(f"\nAppended {len(new_rows)} paraphrased QA pairs to {qna_path}", flush=True)
117
+
118
+
119
+ if __name__ == "__main__":
120
+ main()
scripts/build_doc_embeddings.py ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Embed every document in data/docs/documents.jsonl with the frozen
3
+ Qwen3-Embedding-0.6B encoder (memory_lora/encoder.py) and write
4
+ data/embeddings/doc_embeddings.parquet.
5
+
6
+ Mirrors Code2LoRA's ``create_dataset/build_repo_state_embeddings_shard.py``.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import argparse
12
+ import json
13
+ import sys
14
+ from pathlib import Path
15
+
16
+ import pyarrow as pa
17
+ import pyarrow.parquet as pq
18
+ import torch
19
+ from tqdm import tqdm
20
+
21
+ HERE = Path(__file__).resolve().parent
22
+ REPO_ROOT = HERE.parent
23
+ sys.path.insert(0, str(REPO_ROOT))
24
+ from memory_lora.data_paths import DOCS_DIR, EMBEDDINGS_DIR, ensure_dirs # noqa: E402
25
+ from memory_lora.encoder import DEFAULT_EMBED_MODEL, embed_document, load_encoder # noqa: E402
26
+
27
+
28
+ def main() -> None:
29
+ ap = argparse.ArgumentParser()
30
+ ap.add_argument("--embed-model", default=DEFAULT_EMBED_MODEL)
31
+ ap.add_argument("--device", default="mps")
32
+ ap.add_argument("--chunk-tokens", type=int, default=4096)
33
+ ap.add_argument("--chunk-overlap", type=int, default=512)
34
+ args = ap.parse_args()
35
+
36
+ ensure_dirs()
37
+ docs_path = DOCS_DIR / "documents.jsonl"
38
+ out_path = EMBEDDINGS_DIR / "doc_embeddings.parquet"
39
+
40
+ device = args.device if (args.device != "mps" or torch.backends.mps.is_available()) else "cpu"
41
+ print(f"Loading encoder {args.embed_model} on {device} ...", flush=True)
42
+ model, tokenizer = load_encoder(args.embed_model, device=device)
43
+
44
+ docs = [json.loads(l) for l in docs_path.open()]
45
+ print(f"{len(docs)} documents to embed", flush=True)
46
+
47
+ rows = []
48
+ for d in tqdm(docs):
49
+ sections = [(s["name"], s["text"]) for s in d["sections"]]
50
+ vec = embed_document(
51
+ sections, model, tokenizer, device,
52
+ chunk_tokens=args.chunk_tokens, chunk_overlap=args.chunk_overlap,
53
+ )
54
+ if vec is None:
55
+ print(f" [warn] no embedding for {d['doc_id']}, skipping", flush=True)
56
+ continue
57
+ rows.append({
58
+ "doc_id": d["doc_id"],
59
+ "doc_version": d["doc_version"],
60
+ "split": d["split"],
61
+ "category": d["category"],
62
+ "doc_embedding": vec.numpy().astype("float32").tolist(),
63
+ })
64
+
65
+ table = pa.table({
66
+ "doc_id": [r["doc_id"] for r in rows],
67
+ "doc_version": [r["doc_version"] for r in rows],
68
+ "split": [r["split"] for r in rows],
69
+ "category": [r["category"] for r in rows],
70
+ "doc_embedding": [r["doc_embedding"] for r in rows],
71
+ })
72
+ pq.write_table(table, out_path)
73
+ dim = len(rows[0]["doc_embedding"]) if rows else 0
74
+ print(f"Wrote {len(rows)} embeddings (dim={dim}) -> {out_path}", flush=True)
75
+
76
+
77
+ if __name__ == "__main__":
78
+ main()
scripts/build_repo_multiview.py ADDED
@@ -0,0 +1,245 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Build REAL 6-view repo inputs locally: clone repos, extract the 6
3
+ tech-lead views from each full tree, embed each view with the frozen Qwen
4
+ encoder, concat -> one multi-view repo vector. Also emit a compact per-view
5
+ TEXT summary per repo (so generate_repo_scoped_qa.py can produce
6
+ scope-aligned targets from the SAME views the embedding sees).
7
+
8
+ Views (each -> Qwen mean+max = 2048-d; 6 views -> 12288-d input vector;
9
+ head input_dim is set to match, "~8k" was always approximate):
10
+ v_graph : AST call/import graph (codegraph.py) + dependency edges
11
+ v_arch : READMEs, top-level docstrings, folder tree
12
+ v_history : git log --oneline + sampled commit diffs ("the why")
13
+ v_contracts : test files + type-annotated signatures
14
+ v_conventions: sampled source files (naming/idioms)
15
+ v_ops : Dockerfile / CI yaml / pyproject / setup / .env.example
16
+
17
+ Streaming design: load encoder ONCE, then per repo {clone shallow -> extract
18
+ -> embed -> save -> delete clone} so disk and memory stay bounded. Clone
19
+ failures / oversized / non-Python repos are skipped gracefully.
20
+
21
+ Usage:
22
+ python scripts/build_repo_multiview.py --repos-file data/repo_list.txt --limit 3
23
+ python scripts/build_repo_multiview.py --repos-file data/repo_list.txt --max-repos 250
24
+ """
25
+ from __future__ import annotations
26
+ import argparse, json, os, re, shutil, subprocess, sys, tempfile, time
27
+ from pathlib import Path
28
+ from typing import Dict, List, Optional, Tuple
29
+ import numpy as np, torch
30
+
31
+ HERE = Path(__file__).resolve().parent; REPO_ROOT = HERE.parent
32
+ sys.path.insert(0, str(REPO_ROOT))
33
+ from memory_lora.data_paths import EMBEDDINGS_DIR, DOCS_DIR, ensure_dirs # noqa: E402
34
+ from memory_lora.encoder import load_encoder, embed_document # noqa: E402
35
+ from memory_lora.codegraph import extract_repo_graph_sections, extract_repo_dependency_summary # noqa: E402
36
+
37
+ SKIP = {".git", "__pycache__", ".venv", "venv", "node_modules", "build", "dist",
38
+ ".tox", ".mypy_cache", "vendor", "third_party", "target", ".next"}
39
+ VIEWS = ["v_graph", "v_arch", "v_history", "v_contracts", "v_conventions", "v_ops"]
40
+
41
+ # language-agnostic file classification
42
+ CODE_EXTS = {".py", ".js", ".jsx", ".ts", ".tsx", ".java", ".go", ".rs", ".c",
43
+ ".h", ".cc", ".cpp", ".hpp", ".php", ".rb", ".kt", ".swift", ".scala", ".cs"}
44
+ TEST_HINTS = ("test", "spec", "_test.", ".test.", "tests/")
45
+ # import-statement patterns per common language (for the non-Python graph fallback)
46
+ IMPORT_RE = re.compile(
47
+ r"^\s*(?:import\s+[^\n;]+|from\s+[^\n]+import[^\n]+|#include\s*[<\"][^>\"]+[>\"]|"
48
+ r"use\s+[^\n;]+|require\s*\(?[^\n)]+\)?|package\s+[^\n;]+)", re.MULTILINE)
49
+ DEF_RE = re.compile(
50
+ r"^\s*(?:def\s+\w+|class\s+\w+|func\s+\w+|function\s+\w+|fn\s+\w+|"
51
+ r"(?:public|private|protected|static|\s)+\w[\w<>\[\]]*\s+\w+\s*\(|"
52
+ r"type\s+\w+|struct\s+\w+|interface\s+\w+|export\s+(?:default\s+)?(?:function|class|const)\s+\w+)",
53
+ re.MULTILINE)
54
+
55
+
56
+ def run(cmd: List[str], cwd=None, timeout=120) -> Tuple[int, str]:
57
+ try:
58
+ r = subprocess.run(cmd, cwd=cwd, capture_output=True, text=True,
59
+ errors="ignore", timeout=timeout)
60
+ return r.returncode, r.stdout
61
+ except Exception: # noqa: BLE001
62
+ return 1, ""
63
+
64
+
65
+ def clone(name: str, dest: Path, depth=80) -> bool:
66
+ url = f"https://github.com/{name}.git"
67
+ code, _ = run(["git", "clone", "--depth", str(depth), "--quiet", url, str(dest)], timeout=180)
68
+ return code == 0 and dest.exists()
69
+
70
+
71
+ def _read(p: Path, n=8000) -> str:
72
+ try: return p.read_text(errors="ignore")[:n]
73
+ except OSError: return ""
74
+
75
+
76
+ def _folder_tree(root: Path, max_lines=120) -> str:
77
+ lines = []
78
+ for p in sorted(root.rglob("*")):
79
+ if any(s in p.parts for s in SKIP): continue
80
+ rel = p.relative_to(root)
81
+ if len(rel.parts) > 3: continue
82
+ lines.append(str(rel) + ("/" if p.is_dir() else ""))
83
+ if len(lines) >= max_lines: break
84
+ return "\n".join(lines)
85
+
86
+
87
+ def extract_views(repo: Path) -> Dict[str, List[Tuple[str, str]]]:
88
+ """Return {view_name: [(section_name, text), ...]} for the 6 views."""
89
+ v: Dict[str, List[Tuple[str, str]]] = {k: [] for k in VIEWS}
90
+
91
+ # v_graph: Python AST call/import graph (when present) + language-agnostic
92
+ # regex import/definition summary so non-Python repos still get structure.
93
+ v["v_graph"] = extract_repo_graph_sections(repo, max_files=50, skip_dirs=SKIP)
94
+ dep = extract_repo_dependency_summary(repo, skip_dirs=SKIP)
95
+ if dep: v["v_graph"].append(("dependency_edges", dep))
96
+ if len(v["v_graph"]) < 3: # non-Python (or thin): regex-extract imports/defs
97
+ code = [p for p in repo.rglob("*")
98
+ if p.suffix.lower() in CODE_EXTS and not any(s in p.parts for s in SKIP)][:60]
99
+ imports, defs = [], []
100
+ for p in code:
101
+ t = _read(p, 6000)
102
+ imports += IMPORT_RE.findall(t)[:8]
103
+ defs += [f"{p.name}: {m.strip()[:80]}" for m in DEF_RE.findall(t)[:6]]
104
+ if imports: v["v_graph"].append(("imports", "\n".join(imports[:120])))
105
+ if defs: v["v_graph"].append(("definitions", "\n".join(defs[:120])))
106
+
107
+ # v_arch: READMEs, folder tree, package docstrings
108
+ for pat in ["README*", "ARCHITECTURE*", "docs/*.md", "*/__init__.py"]:
109
+ for p in list(repo.glob(pat))[:4]:
110
+ if p.is_file(): v["v_arch"].append((f"arch:{p.name}", _read(p, 6000)))
111
+ v["v_arch"].append(("folder_tree", _folder_tree(repo)))
112
+
113
+ # v_history: git log + a few diffs
114
+ _, log = run(["git", "-C", str(repo), "log", "--oneline", "-80"])
115
+ if log: v["v_history"].append(("git_log", log[:6000]))
116
+ _, shas = run(["git", "-C", str(repo), "log", "--format=%H", "-6"])
117
+ for sha in [s for s in shas.split() if s][:5]:
118
+ _, diff = run(["git", "-C", str(repo), "show", "--stat", "-p", sha])
119
+ if diff: v["v_history"].append((f"diff:{sha[:8]}", diff[:3000]))
120
+
121
+ # v_contracts: test files (any language) + typed signatures
122
+ tests = [p for p in repo.rglob("*")
123
+ if p.suffix.lower() in CODE_EXTS and not any(s in p.parts for s in SKIP)
124
+ and any(h in str(p).lower() for h in TEST_HINTS)][:10]
125
+ for p in tests:
126
+ v["v_contracts"].append((f"test:{p.name}", _read(p, 4000)))
127
+
128
+ # v_conventions: sampled source files (any language, non-test)
129
+ srcs = [p for p in repo.rglob("*")
130
+ if p.suffix.lower() in CODE_EXTS and not any(s in p.parts for s in SKIP)
131
+ and not any(h in str(p).lower() for h in TEST_HINTS)][:12]
132
+ for p in srcs:
133
+ v["v_conventions"].append((f"src:{p.name}", _read(p, 3500)))
134
+
135
+ # v_ops: build/CI/config
136
+ for pat in ["Dockerfile*", ".github/workflows/*.y*ml", "pyproject.toml",
137
+ "setup.py", "setup.cfg", "requirements*.txt", "Makefile", ".env.example",
138
+ "docker-compose*.y*ml", "tox.ini"]:
139
+ for p in list(repo.glob(pat))[:3]:
140
+ if p.is_file(): v["v_ops"].append((f"ops:{p.name}", _read(p, 4000)))
141
+ return v
142
+
143
+
144
+ def summarize_views_text(views: Dict[str, List[Tuple[str, str]]], per_view=1400) -> Dict[str, str]:
145
+ """Compact text per view for QA generation (scope-aligned to embedding)."""
146
+ out = {}
147
+ for k, secs in views.items():
148
+ joined = "\n".join(f"# {n}\n{t}" for n, t in secs)
149
+ out[k] = joined[:per_view]
150
+ return out
151
+
152
+
153
+ def main():
154
+ ap = argparse.ArgumentParser()
155
+ ap.add_argument("--repos-file", required=True)
156
+ ap.add_argument("--max-repos", type=int, default=250)
157
+ ap.add_argument("--limit", type=int, default=0)
158
+ ap.add_argument("--device", default="mps")
159
+ ap.add_argument("--out-emb", default=str(EMBEDDINGS_DIR / "multiview_embeddings.parquet"))
160
+ ap.add_argument("--out-src", default=str(DOCS_DIR / "multiview_sources.jsonl"))
161
+ args = ap.parse_args()
162
+ ensure_dirs()
163
+
164
+ target = args.limit if args.limit else args.max_repos
165
+ # accept "repo" or "repo<TAB>lang" lines; keep the lang tag if present
166
+ name_lang = []
167
+ for l in open(args.repos_file):
168
+ l = l.strip()
169
+ if not l: continue
170
+ parts = l.split("\t")
171
+ name_lang.append((parts[0], parts[1] if len(parts) > 1 else "unknown"))
172
+ name_lang = name_lang[: target * 3] # oversample for clone failures
173
+ names = [n for n, _ in name_lang]
174
+ lang_of = dict(name_lang)
175
+
176
+ device = args.device if (args.device != "mps" or torch.backends.mps.is_available()) else "cpu"
177
+ print(f"Loading Qwen encoder on {device} ...", flush=True)
178
+ enc_model, enc_tok = load_encoder(device=device)
179
+
180
+ # resume-safe: skip repos already done
181
+ done = set()
182
+ if Path(args.out_src).exists():
183
+ done = {json.loads(l)["repo"] for l in open(args.out_src)}
184
+ src_f = open(args.out_src, "a")
185
+
186
+ import pyarrow as pa, pyarrow.parquet as pq
187
+ emb_rows = []
188
+ # load existing embeddings if resuming
189
+ if Path(args.out_emb).exists():
190
+ t = pq.read_table(args.out_emb).to_pylist()
191
+ emb_rows = t
192
+
193
+ n_done = 0; t0 = time.time()
194
+ for name in names:
195
+ if n_done >= target: break
196
+ if name in done: continue
197
+ tmp = Path(tempfile.mkdtemp(prefix="rmv_"))
198
+ try:
199
+ if not clone(name, tmp / "r"):
200
+ continue
201
+ repo = tmp / "r"
202
+ # skip repos with too little code (any language)
203
+ codefiles = [p for p in repo.rglob("*")
204
+ if p.suffix.lower() in CODE_EXTS and not any(s in p.parts for s in SKIP)]
205
+ if len(codefiles) < 3:
206
+ continue
207
+ views = extract_views(repo)
208
+ # embed each view -> mean+max 2048; concat 6 -> 12288
209
+ vecs = []
210
+ for vk in VIEWS:
211
+ secs = views[vk] or [("empty", "none")]
212
+ vv = embed_document(secs, enc_model, enc_tok, device,
213
+ chunk_tokens=2048, chunk_overlap=128, batch_size=2)
214
+ vecs.append(vv.numpy().astype("float32") if vv is not None else np.zeros(2048, "float32"))
215
+ full = np.concatenate(vecs) # 12288
216
+ doc_id = name # repo-scoped
217
+ emb_rows.append({"doc_id": doc_id, "doc_version": "head", "split": "train",
218
+ "category": "real_repo_multiview", "doc_embedding": full.tolist()})
219
+ src_f.write(json.dumps({"repo": name, "doc_id": doc_id,
220
+ "lang": lang_of.get(name, "unknown"),
221
+ "view_text": summarize_views_text(views)}) + "\n")
222
+ src_f.flush()
223
+ n_done += 1
224
+ if n_done % 10 == 0:
225
+ rate = n_done / max(1e-9, (time.time() - t0) / 60)
226
+ # periodic parquet flush
227
+ _flush(emb_rows, args.out_emb, pa, pq)
228
+ print(f" {n_done} repos done ({rate:.1f}/min) dim={full.shape[0]} latest={name}", flush=True)
229
+ finally:
230
+ shutil.rmtree(tmp, ignore_errors=True)
231
+
232
+ _flush(emb_rows, args.out_emb, pa, pq)
233
+ src_f.close()
234
+ print(f"\nDone. {n_done} repos -> {args.out_emb} (dim={len(emb_rows[0]['doc_embedding']) if emb_rows else 0})", flush=True)
235
+
236
+
237
+ def _flush(rows, path, pa, pq):
238
+ if not rows: return
239
+ t = pa.table({k: [r[k] for r in rows] for k in
240
+ ["doc_id", "doc_version", "split", "category", "doc_embedding"]})
241
+ pq.write_table(t, path)
242
+
243
+
244
+ if __name__ == "__main__":
245
+ main()
scripts/consolidate_qa.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Consolidate all tech-lead QA sources into one balanced training file with
3
+ a PER-REPO CAP, so no single repo/domain dominates. This is what fixes the
4
+ Django problem: SWE-bench inherently has ~5 Python repos (django-dominated)
5
+ with thousands of QA already generated; capping per repo collapses django
6
+ from ~2200 to <=CAP while keeping the 700+ distinct repos' diversity.
7
+
8
+ Reads: data/qna/techlead_qa.jsonl, techlead_qa_commitpack.jsonl,
9
+ repo_scoped_qa.jsonl (+ optional multilang tags)
10
+ Writes: data/qna/techlead_consolidated.jsonl
11
+ """
12
+ from __future__ import annotations
13
+ import argparse, json, glob, random, sys
14
+ from collections import Counter, defaultdict
15
+ from pathlib import Path
16
+ HERE = Path(__file__).resolve().parent; REPO_ROOT = HERE.parent
17
+ sys.path.insert(0, str(REPO_ROOT))
18
+ from memory_lora.data_paths import QNA_DIR
19
+
20
+ def repo_of(doc_id): return doc_id.split("@")[0]
21
+
22
+ def main():
23
+ ap = argparse.ArgumentParser()
24
+ ap.add_argument("--per-repo-cap", type=int, default=15)
25
+ ap.add_argument("--out", default=str(QNA_DIR / "techlead_consolidated.jsonl"))
26
+ args = ap.parse_args()
27
+ rng = random.Random(3407)
28
+
29
+ files = [QNA_DIR / "techlead_qa.jsonl", QNA_DIR / "techlead_qa_commitpack.jsonl",
30
+ QNA_DIR / "repo_scoped_qa.jsonl"]
31
+ by_repo = defaultdict(list)
32
+ for f in files:
33
+ if not f.exists(): continue
34
+ for l in open(f):
35
+ try: d = json.loads(l)
36
+ except json.JSONDecodeError: continue
37
+ by_repo[repo_of(d["doc_id"])].append(d)
38
+
39
+ kept = []
40
+ for repo, rows in by_repo.items():
41
+ if len(rows) > args.per_repo_cap:
42
+ rows = rng.sample(rows, args.per_repo_cap)
43
+ kept.extend(rows)
44
+ rng.shuffle(kept)
45
+
46
+ with open(args.out, "w") as fo:
47
+ for d in kept: fo.write(json.dumps(d) + "\n")
48
+
49
+ langs = Counter(d.get("lang", "python?") for d in kept)
50
+ repos = Counter(repo_of(d["doc_id"]) for d in kept)
51
+ django = sum(v for k, v in repos.items() if "django" in k.lower())
52
+ print(f"consolidated: {len(kept)} QA | {len(repos)} distinct repos | cap={args.per_repo_cap}/repo")
53
+ print(f" django share: {django} ({100*django/max(1,len(kept)):.1f}%) <- was 46%")
54
+ print(f" langs: {dict(langs)}")
55
+ print(f" top repos: {repos.most_common(5)}")
56
+ print(f" -> {args.out}")
57
+
58
+ if __name__ == "__main__":
59
+ main()
scripts/convert_real_code2lora.py ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Convert the REAL Code2LoRA/RepoPeftBench datasets into our local schema.
3
+
4
+ Sources (downloaded from HF under data/real_code2lora/):
5
+ * code2lora-evo -- PRIMARY. Full per-commit history for all
6
+ 400 train + 49 cr_val + 51 cr_test repos (58,617 commit rows for train
7
+ alone), each with repo_state_embedding (2048-d), diff_embedding
8
+ (2048-d, embeds production_code_diff), and the literal
9
+ production_code_diff text. QnA files (train/ir_val/ir_test/cr_val/
10
+ cr_test) carry assertion_event_type + old_target -- i.e. this is real
11
+ diff/change data, not just static snapshots.
12
+ * code2lora-static-anchor -- supplementary: qna/train.parquet has the
13
+ static-track anchor-based QnAs (different extraction protocol than
14
+ evo's train QnAs -- both are valid, kept as separate rows).
15
+ * repopeftbench-ood -- 92-repo temporal holdout, used only for
16
+ held-out evaluation, never trained on.
17
+
18
+ Output (appended, not overwritten, so re-running is additive-safe against
19
+ accidental double-runs is NOT guaranteed -- this script always rewrites
20
+ its own output files from scratch):
21
+ data/embeddings/real_code2lora_embeddings.parquet
22
+ doc_id = f"{repo_id}@{commit_sha[:10]}", doc_embedding = repo_state_embedding
23
+ data/qna/real_code2lora_qna.jsonl
24
+ one row per assertion-completion task, joined against the embeddings
25
+ above via the real (repo_id, commit_sha) pair (never guessed).
26
+ data/embeddings/real_code2lora_diffs.parquet
27
+ doc_id = f"{repo_id}@{commit_sha[:10]}", diff_embedding, and the raw
28
+ production_code_diff text -- kept SEPARATE from repo_state so a
29
+ future "what changed at this commit" task can condition on the diff
30
+ specifically rather than the whole-repo snapshot.
31
+
32
+ Usage:
33
+ python scripts/convert_real_code2lora.py
34
+ """
35
+
36
+ from __future__ import annotations
37
+
38
+ import json
39
+ import sys
40
+ from pathlib import Path
41
+ from typing import Dict, Set, Tuple
42
+
43
+ import pyarrow as pa
44
+ import pyarrow.parquet as pq
45
+
46
+ HERE = Path(__file__).resolve().parent
47
+ REPO_ROOT = HERE.parent
48
+ sys.path.insert(0, str(REPO_ROOT))
49
+ from memory_lora.data_paths import DATA_ROOT, EMBEDDINGS_DIR, QNA_DIR, ensure_dirs # noqa: E402
50
+
51
+ REAL_ROOT = DATA_ROOT / "real_code2lora"
52
+ EVO_ROOT = REAL_ROOT / "code2lora-evo"
53
+ ANCHOR_ROOT = REAL_ROOT / "code2lora-static-anchor"
54
+ OOD_ROOT = REAL_ROOT / "repopeftbench-ood"
55
+
56
+
57
+ def _doc_id(repo_id: str, commit_sha: str) -> str:
58
+ return f"{repo_id}@{str(commit_sha)[:10]}"
59
+
60
+
61
+ def convert_embeddings_and_diffs() -> Set[Tuple[str, str]]:
62
+ """evo/commits/{split}.parquet -> repo-state embeddings AND diff
63
+ embeddings (kept in separate output files). Returns the set of
64
+ (repo_id, commit_sha) pairs with a real embedding, for the QnA join."""
65
+ emb_rows, diff_rows = [], []
66
+ valid_keys: Set[Tuple[str, str]] = set()
67
+ seen_ids: Set[str] = set()
68
+
69
+ for split_file, split_label in [
70
+ ("train.parquet", "train"), ("cr_val.parquet", "cr_val"), ("cr_test.parquet", "cr_test"),
71
+ ]:
72
+ path = EVO_ROOT / "commits" / split_file
73
+ if not path.exists():
74
+ print(f" [skip] {path} not found", flush=True)
75
+ continue
76
+ table = pq.read_table(path, columns=[
77
+ "repo_id", "commit_sha", "repo_state_embedding", "diff_embedding", "production_code_diff",
78
+ ])
79
+ n = table.num_rows
80
+ repo_col = table.column("repo_id").to_pylist()
81
+ sha_col = table.column("commit_sha").to_pylist()
82
+ emb_col = table.column("repo_state_embedding").to_pylist()
83
+ diff_emb_col = table.column("diff_embedding").to_pylist()
84
+ diff_text_col = table.column("production_code_diff").to_pylist()
85
+ for i in range(n):
86
+ key = (repo_col[i], sha_col[i])
87
+ valid_keys.add(key)
88
+ doc_id = _doc_id(*key)
89
+ if doc_id not in seen_ids:
90
+ seen_ids.add(doc_id)
91
+ emb_rows.append({
92
+ "doc_id": doc_id, "doc_version": sha_col[i],
93
+ "split": split_label, "category": "real_code_repo",
94
+ "doc_embedding": emb_col[i],
95
+ })
96
+ if diff_emb_col[i] is not None:
97
+ diff_rows.append({
98
+ "doc_id": doc_id, "doc_version": sha_col[i], "split": split_label,
99
+ "diff_embedding": diff_emb_col[i],
100
+ "diff_text": (diff_text_col[i] or "")[:4000],
101
+ })
102
+ print(f" evo {split_label}: {n} (repo, commit) rows, {len(set(repo_col))} unique repos", flush=True)
103
+
104
+ # supplementary: OOD holdout (from static-anchor, evo has no OOD split)
105
+ ood_file = OOD_ROOT / "ood_test.parquet"
106
+ if ood_file.exists():
107
+ table = pq.read_table(ood_file)
108
+ if "repo_state_embedding" in table.column_names:
109
+ n = table.num_rows
110
+ repo_col = table.column("repo_id").to_pylist()
111
+ sha_col = table.column("commit_sha").to_pylist()
112
+ emb_col = table.column("repo_state_embedding").to_pylist()
113
+ for i in range(n):
114
+ key = (repo_col[i], sha_col[i])
115
+ valid_keys.add(key)
116
+ doc_id = _doc_id(*key)
117
+ if doc_id not in seen_ids:
118
+ seen_ids.add(doc_id)
119
+ emb_rows.append({
120
+ "doc_id": doc_id, "doc_version": sha_col[i],
121
+ "split": "cr_test", "category": "real_code_repo_ood",
122
+ "doc_embedding": emb_col[i],
123
+ })
124
+ print(f" ood: {n} (repo, commit) rows, {len(set(repo_col))} unique repos", flush=True)
125
+
126
+ emb_table = pa.table({
127
+ "doc_id": [r["doc_id"] for r in emb_rows],
128
+ "doc_version": [r["doc_version"] for r in emb_rows],
129
+ "split": [r["split"] for r in emb_rows],
130
+ "category": [r["category"] for r in emb_rows],
131
+ "doc_embedding": [r["doc_embedding"] for r in emb_rows],
132
+ })
133
+ emb_path = EMBEDDINGS_DIR / "real_code2lora_embeddings.parquet"
134
+ pq.write_table(emb_table, emb_path)
135
+ print(f"Wrote {len(emb_rows)} real repo embeddings -> {emb_path}", flush=True)
136
+
137
+ diff_table = pa.table({
138
+ "doc_id": [r["doc_id"] for r in diff_rows],
139
+ "doc_version": [r["doc_version"] for r in diff_rows],
140
+ "split": [r["split"] for r in diff_rows],
141
+ "diff_embedding": [r["diff_embedding"] for r in diff_rows],
142
+ "diff_text": [r["diff_text"] for r in diff_rows],
143
+ })
144
+ diff_path = EMBEDDINGS_DIR / "real_code2lora_diffs.parquet"
145
+ pq.write_table(diff_table, diff_path)
146
+ print(f"Wrote {len(diff_rows)} real diff embeddings -> {diff_path}", flush=True)
147
+
148
+ return valid_keys
149
+
150
+
151
+ def convert_qna(valid_keys: Set[Tuple[str, str]]) -> int:
152
+ """evo/qna/{split}.parquet (primary) + static-anchor/qna/train.parquet
153
+ (supplementary static-track anchors) -> our jsonl rows, joined against
154
+ valid_keys (only keep QnAs whose (repo_id, commit_sha) has a real
155
+ embedding)."""
156
+ out_path = QNA_DIR / "real_code2lora_qna.jsonl"
157
+ n_written, n_dropped = 0, 0
158
+
159
+ sources = [
160
+ (EVO_ROOT / "qna" / "train.parquet", "train", "train"),
161
+ (EVO_ROOT / "qna" / "ir_val.parquet", "train", "held_out"),
162
+ (EVO_ROOT / "qna" / "ir_test.parquet", "train", "held_out"),
163
+ (EVO_ROOT / "qna" / "cr_val.parquet", "cr_val", "held_out"),
164
+ (EVO_ROOT / "qna" / "cr_test.parquet", "cr_test", "held_out"),
165
+ (ANCHOR_ROOT / "qna" / "train.parquet", "train", "train"),
166
+ ]
167
+ with out_path.open("w") as f:
168
+ for path, doc_split, qna_split in sources:
169
+ if not path.exists():
170
+ print(f" [skip] {path} not found", flush=True)
171
+ continue
172
+ table = pq.read_table(path, columns=["repo_id", "commit_sha", "prefix", "target"])
173
+ n = table.num_rows
174
+ repo_col = table.column("repo_id").to_pylist()
175
+ sha_col = table.column("commit_sha").to_pylist()
176
+ prefix_col = table.column("prefix").to_pylist()
177
+ target_col = table.column("target").to_pylist()
178
+ kept = 0
179
+ for i in range(n):
180
+ key = (repo_col[i], sha_col[i])
181
+ if key not in valid_keys:
182
+ n_dropped += 1
183
+ continue
184
+ f.write(json.dumps({
185
+ "doc_id": _doc_id(repo_col[i], sha_col[i]), "doc_version": sha_col[i],
186
+ "split": doc_split, "qna_split": qna_split,
187
+ "question": "", "prefix": prefix_col[i], "target": target_col[i],
188
+ }) + "\n")
189
+ n_written += 1
190
+ kept += 1
191
+ print(f" {path.parent.parent.name}/{path.name}: {kept}/{n} QnAs matched "
192
+ f"-> split={doc_split} qna_split={qna_split}", flush=True)
193
+ print(f"Wrote {n_written} real QnA pairs ({n_dropped} dropped, no matching "
194
+ f"embedding) -> {out_path}", flush=True)
195
+ return n_written
196
+
197
+
198
+ def main() -> None:
199
+ ensure_dirs()
200
+ print("Converting real repo + diff embeddings (from code2lora-evo)...", flush=True)
201
+ valid_keys = convert_embeddings_and_diffs()
202
+ print(f"\n{len(valid_keys)} valid (repo, commit) embedding keys found.\n", flush=True)
203
+ print("Converting real QnA pairs (joined against real embeddings)...", flush=True)
204
+ n_qna = convert_qna(valid_keys)
205
+ print(f"\nDone: {len(valid_keys)} real repo-commit docs, {n_qna} real QnA pairs.", flush=True)
206
+
207
+
208
+ if __name__ == "__main__":
209
+ main()
scripts/diag_mps_leak.py ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Isolated MPS memory-leak diagnostic.
3
+
4
+ Runs a minimal train-step loop on REAL code prefixes and prints
5
+ system-available memory after every single operation, aborting the moment
6
+ it crosses a hard floor. Tests one variable at a time (gradient
7
+ checkpointing on/off, empty_cache on/off) so we can pinpoint what actually
8
+ leaks, without the full training harness in the way.
9
+ """
10
+ from __future__ import annotations
11
+ import argparse, json, sys, time
12
+ from pathlib import Path
13
+ import psutil, torch, torch.nn.functional as F
14
+ HERE = Path(__file__).resolve().parent; REPO_ROOT = HERE.parent
15
+ sys.path.insert(0, str(REPO_ROOT))
16
+ from memory_lora.core import (MemoryLoRAHead, get_module_specs, discover_module_types_and_dims,
17
+ inject_lora_weights, replace_with_lora, DEFAULT_ROOT_PREFIX)
18
+ from transformers import AutoModelForImageTextToText, AutoTokenizer
19
+
20
+ TARGET_MODULES = ["q_proj","k_proj","v_proj","o_proj","up_proj","gate_proj","down_proj"]
21
+
22
+ def avail_gb(): return psutil.virtual_memory().available / 1e9
23
+
24
+ def main():
25
+ ap = argparse.ArgumentParser()
26
+ ap.add_argument("--grad-checkpoint", action="store_true")
27
+ ap.add_argument("--empty-cache-every", type=int, default=0, help="0=never")
28
+ ap.add_argument("--steps", type=int, default=10)
29
+ ap.add_argument("--seq-len", type=int, default=512)
30
+ ap.add_argument("--micro-batch", type=int, default=2)
31
+ ap.add_argument("--floor-gb", type=float, default=22.0)
32
+ ap.add_argument("--train", action="store_true", help="do backward (else forward-only)")
33
+ args = ap.parse_args()
34
+ device = torch.device("mps")
35
+
36
+ print(f"[cfg] grad_ckpt={args.grad_checkpoint} empty_cache_every={args.empty_cache_every} "
37
+ f"train={args.train} seq={args.seq_len} mb={args.micro_batch}", flush=True)
38
+ print(f"[mem] start avail={avail_gb():.1f}GB", flush=True)
39
+
40
+ tok = AutoTokenizer.from_pretrained("google/gemma-4-E2B")
41
+ if tok.pad_token is None: tok.pad_token = tok.eos_token
42
+ model = AutoModelForImageTextToText.from_pretrained(
43
+ "google/gemma-4-E2B", torch_dtype=torch.bfloat16, attn_implementation="sdpa").to(device)
44
+ model.eval()
45
+ for p in model.parameters(): p.requires_grad = False
46
+ print(f"[mem] after model load avail={avail_gb():.1f}GB", flush=True)
47
+ if args.grad_checkpoint:
48
+ model.config.use_cache = False
49
+ model.gradient_checkpointing_enable(gradient_checkpointing_kwargs={"use_reentrant": False})
50
+ print(" gradient checkpointing ON", flush=True)
51
+
52
+ specs = get_module_specs(model, TARGET_MODULES, root_prefix=DEFAULT_ROOT_PREFIX)
53
+ type_dims = discover_module_types_and_dims(specs)
54
+ replace_with_lora(model, specs, rank=16, alpha=32.0)
55
+ head = MemoryLoRAHead(input_dim=2048, type_dims=type_dims, hidden_dim=512, rank=16).to(device)
56
+ print(f"[mem] after head+lora avail={avail_gb():.1f}GB", flush=True)
57
+
58
+ # real prefixes
59
+ prefixes, targets = [], []
60
+ with open(REPO_ROOT / "data/qna/real_code2lora_qna.jsonl") as f:
61
+ for line in f:
62
+ d = json.loads(line); prefixes.append(d["prefix"]); targets.append(d["target"])
63
+ if len(prefixes) >= args.steps * args.micro_batch: break
64
+ ctx = torch.randn(1, 2048, device=device)
65
+
66
+ for step in range(args.steps):
67
+ if avail_gb() < args.floor_gb:
68
+ print(f"[ABORT] avail={avail_gb():.1f}GB < floor {args.floor_gb} at step {step}", flush=True)
69
+ break
70
+ i0 = step * args.micro_batch
71
+ ps = prefixes[i0:i0+args.micro_batch]; ts = targets[i0:i0+args.micro_batch]
72
+ ids_list, lab_list = [], []
73
+ for p, t in zip(ps, ts):
74
+ tids = tok(t + (tok.eos_token or ""), add_special_tokens=False)["input_ids"]
75
+ pids = tok(p, add_special_tokens=False)["input_ids"]
76
+ budget = max(8, args.seq_len - len(tids)); pids = pids[-budget:]
77
+ ids = pids + tids; lab = [-100]*len(pids) + list(tids)
78
+ ids_list.append(torch.tensor(ids)); lab_list.append(torch.tensor(lab))
79
+ L = args.seq_len
80
+ pad = tok.pad_token_id or 0
81
+ def lp(x, v): return F.pad(x, (L-x.size(0),0), value=v) if x.size(0)<=L else x[-L:]
82
+ input_ids = torch.stack([lp(t,pad) for t in ids_list]).to(device)
83
+ labels = torch.stack([lp(t,-100) for t in lab_list]).to(device)
84
+ attn = (input_ids != pad).long().to(device)
85
+ head_out = head(ctx); inject_lora_weights(model, specs, head_out, batch_index=0)
86
+ if args.train:
87
+ out = model(input_ids=input_ids, attention_mask=attn, labels=labels)
88
+ (out.loss).backward()
89
+ head.zero_grad(set_to_none=True)
90
+ else:
91
+ with torch.no_grad():
92
+ out = model(input_ids=input_ids, attention_mask=attn, labels=labels)
93
+ loss_val = out.loss.item()
94
+ del head_out, out
95
+ if args.empty_cache_every and step % args.empty_cache_every == 0:
96
+ torch.mps.empty_cache()
97
+ print(f"[step {step}] loss={loss_val:.3f} avail={avail_gb():.1f}GB", flush=True)
98
+ print(f"[done] final avail={avail_gb():.1f}GB", flush=True)
99
+
100
+ if __name__ == "__main__":
101
+ main()
scripts/eval_memory_lora.py ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Evaluate a trained Memory-LoRA head: recall EM/EditSim on held-out QA,
3
+ split into in-corpus (ir_test) and cross-corpus (cr_val/cr_test), plus a
4
+ manual spot-check comparing the LoRA-adapted model against the bare base
5
+ model on hand-picked Code2LoRA-paper questions (proof the adapter, not
6
+ general pretraining, is doing the recall).
7
+
8
+ Forked from Code2LoRA's evaluation metrics (EM after whitespace collapsing
9
+ + trailing-punctuation removal with relaxed prefix matching; EditSim via
10
+ difflib.SequenceMatcher).
11
+
12
+ Usage:
13
+ python scripts/eval_memory_lora.py --checkpoint runs/full1/head.best.pt
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import argparse
19
+ import difflib
20
+ import json
21
+ import re
22
+ import sys
23
+ from pathlib import Path
24
+ from typing import Any, Dict, List
25
+
26
+ import torch
27
+ from transformers import AutoModelForImageTextToText, AutoTokenizer
28
+
29
+ HERE = Path(__file__).resolve().parent
30
+ REPO_ROOT = HERE.parent
31
+ sys.path.insert(0, str(REPO_ROOT))
32
+ from memory_lora.data_paths import EMBEDDINGS_DIR, QNA_DIR # noqa: E402
33
+ from memory_lora.core import ( # noqa: E402
34
+ MemoryLoRAHead,
35
+ DEFAULT_ROOT_PREFIX,
36
+ get_module_specs,
37
+ inject_lora_weights,
38
+ load_doc_rows,
39
+ load_qna_rows,
40
+ replace_with_lora,
41
+ )
42
+
43
+ DEFAULT_MODEL = "google/gemma-4-E2B"
44
+ DEFAULT_TARGET_MODULES = [
45
+ "q_proj", "k_proj", "v_proj", "o_proj",
46
+ "up_proj", "gate_proj", "down_proj",
47
+ ]
48
+
49
+ SPOT_CHECK_QUESTIONS = [
50
+ ("What LoRA rank does Code2LoRA's static hypernetwork use?", "16"),
51
+ ("How many trainable parameters does Code2LoRA-Static have?", "720 million"),
52
+ ("What is the cross-repo exact match of Code2LoRA-Static on the static track?", "63.8%"),
53
+ ("How many Python repositories are in RepoPeftBench?", "604"),
54
+ ("What is the base LLM used in Code2LoRA's experiments?", "Qwen2.5-Coder-1.5B"),
55
+ ]
56
+
57
+
58
+ def normalize(s: str) -> str:
59
+ s = s.strip().rstrip(".,;:!?")
60
+ s = re.sub(r"\s+", " ", s)
61
+ return s.lower()
62
+
63
+
64
+ def exact_match(pred: str, target: str) -> bool:
65
+ p, t = normalize(pred), normalize(target)
66
+ return p == t or p.startswith(t) or t.startswith(p)
67
+
68
+
69
+ def edit_sim(pred: str, target: str) -> float:
70
+ return difflib.SequenceMatcher(None, normalize(pred), normalize(target)).ratio()
71
+
72
+
73
+ @torch.no_grad()
74
+ def generate(base_model, tokenizer, prefix: str, device, max_new_tokens: int = 12) -> str:
75
+ """Greedy-decode the answer, then truncate at the first newline.
76
+
77
+ Without this the model frequently keeps going past the answer into a
78
+ hallucinated ``\\nQ: <next question>`` continuation (base models without
79
+ an EOS-triggering chat template rarely stop cleanly on a bare
80
+ completion prompt); comparing the *untruncated* string against the gold
81
+ answer would mark an otherwise-correct short answer wrong just because
82
+ of what it rambled into afterward.
83
+ """
84
+ enc = tokenizer(prefix, return_tensors="pt").to(device)
85
+ out = base_model.generate(
86
+ **enc, max_new_tokens=max_new_tokens, do_sample=False,
87
+ pad_token_id=tokenizer.pad_token_id or tokenizer.eos_token_id,
88
+ )
89
+ gen_ids = out[0][enc["input_ids"].shape[1]:]
90
+ text = tokenizer.decode(gen_ids, skip_special_tokens=True)
91
+ return text.split("\n")[0]
92
+
93
+
94
+ def load_head_and_model(checkpoint: Path, model_name: str, target_modules: List[str],
95
+ root_prefix: str, device: torch.device, dtype: torch.dtype,
96
+ attn_implementation: str):
97
+ ckpt = torch.load(checkpoint, map_location="cpu")
98
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
99
+ if tokenizer.pad_token is None:
100
+ tokenizer.pad_token = tokenizer.eos_token
101
+ base_model = AutoModelForImageTextToText.from_pretrained(
102
+ model_name, torch_dtype=dtype, attn_implementation=attn_implementation,
103
+ ).to(device)
104
+ base_model.eval()
105
+ for p in base_model.parameters():
106
+ p.requires_grad = False
107
+
108
+ specs = get_module_specs(base_model, target_modules, root_prefix=root_prefix)
109
+ rank = ckpt["config"]["rank"]
110
+ alpha = ckpt["args"].get("alpha", 32.0)
111
+ replace_with_lora(base_model, specs, rank=rank, alpha=alpha)
112
+
113
+ head = MemoryLoRAHead(
114
+ input_dim=ckpt["config"]["input_dim"],
115
+ type_dims={k: tuple(v) for k, v in ckpt["config"]["type_dims"].items()},
116
+ hidden_dim=ckpt["config"]["hidden_dim"],
117
+ rank=rank,
118
+ ).to(device)
119
+ head.load_state_dict(ckpt["state_dict"])
120
+ head.eval()
121
+ return base_model, head, specs, tokenizer
122
+
123
+
124
+ def eval_suite(base_model, head, specs, tokenizer, doc_rows, qnas_by_doc, device,
125
+ max_qna_per_doc: int = 20) -> Dict[str, float]:
126
+ n_em, n_total, sum_editsim = 0, 0, 0.0
127
+ for dr in doc_rows:
128
+ pairs = qnas_by_doc.get(dr.doc_id, [])[:max_qna_per_doc]
129
+ if not pairs:
130
+ continue
131
+ ctx = torch.from_numpy(dr.doc_embedding).to(device).unsqueeze(0)
132
+ head_out = head(ctx)
133
+ inject_lora_weights(base_model, specs, head_out, batch_index=0)
134
+ for p in pairs:
135
+ pred = generate(base_model, tokenizer, p["prefix"], device)
136
+ target = p["target"]
137
+ if exact_match(pred, target):
138
+ n_em += 1
139
+ sum_editsim += edit_sim(pred, target)
140
+ n_total += 1
141
+ return {
142
+ "em": n_em / max(n_total, 1),
143
+ "editsim": sum_editsim / max(n_total, 1),
144
+ "n": n_total,
145
+ }
146
+
147
+
148
+ def main() -> None:
149
+ ap = argparse.ArgumentParser()
150
+ ap.add_argument("--checkpoint", required=True)
151
+ ap.add_argument("--embeddings-path", default=str(EMBEDDINGS_DIR / "doc_embeddings.parquet"))
152
+ ap.add_argument("--qna-path", default=str(QNA_DIR / "qna.jsonl"))
153
+ ap.add_argument("--model-name", default=DEFAULT_MODEL)
154
+ ap.add_argument("--target-modules", nargs="+", default=DEFAULT_TARGET_MODULES)
155
+ ap.add_argument("--root-prefix", default=DEFAULT_ROOT_PREFIX)
156
+ ap.add_argument("--device", default="mps")
157
+ ap.add_argument("--dtype", default="bfloat16", choices=["bfloat16", "float16", "float32"])
158
+ ap.add_argument("--attn-implementation", default="sdpa", choices=["sdpa", "eager"])
159
+ ap.add_argument("--suites", nargs="+", default=["cr_val", "cr_test", "ir_test"])
160
+ ap.add_argument("--max-qna-per-doc", type=int, default=20)
161
+ ap.add_argument("--limit-docs", type=int, default=0,
162
+ help="Random-sample at most N docs per suite (fixed seed) "
163
+ "for a fast estimate -- cr_test has thousands of real "
164
+ "repos, far too many to greedy-generate on CPU.")
165
+ ap.add_argument("--skip-spot-check", action="store_true")
166
+ args = ap.parse_args()
167
+
168
+ device = torch.device(args.device if (args.device != "mps" or torch.backends.mps.is_available()) else "cpu")
169
+ dtype = {"bfloat16": torch.bfloat16, "float16": torch.float16, "float32": torch.float32}[args.dtype]
170
+
171
+ base_model, head, specs, tokenizer = load_head_and_model(
172
+ Path(args.checkpoint), args.model_name, args.target_modules,
173
+ args.root_prefix, device, dtype, args.attn_implementation,
174
+ )
175
+
176
+ all_docs = load_doc_rows(Path(args.embeddings_path))
177
+ all_qnas = load_qna_rows(Path(args.qna_path))
178
+ qnas_by_doc_all = {}
179
+ qnas_held_out_by_doc = {}
180
+ for q in all_qnas:
181
+ qnas_by_doc_all.setdefault(q.doc_id, []).append({"prefix": q.prefix, "target": q.target})
182
+ if q.qna_split == "held_out":
183
+ qnas_held_out_by_doc.setdefault(q.doc_id, []).append({"prefix": q.prefix, "target": q.target})
184
+ train_docs = [d for d in all_docs if d.split == "train"]
185
+
186
+ results: Dict[str, Any] = {}
187
+ for suite in args.suites:
188
+ if suite in ("cr_val", "cr_test"):
189
+ rows, q_by_doc = [d for d in all_docs if d.split == suite], qnas_by_doc_all
190
+ elif suite == "ir_test":
191
+ rows, q_by_doc = train_docs, qnas_held_out_by_doc
192
+ else:
193
+ continue
194
+ if args.limit_docs and len(rows) > args.limit_docs:
195
+ import random as _r
196
+ rows = _r.Random(3407).sample(rows, args.limit_docs)
197
+ print(f"Evaluating {suite} ({len(rows)} docs) ...", flush=True)
198
+ m = eval_suite(base_model, head, specs, tokenizer, rows, q_by_doc, device,
199
+ max_qna_per_doc=args.max_qna_per_doc)
200
+ results[suite] = m
201
+ print(f" {suite}: EM={m['em']:.3f} EditSim={m['editsim']:.3f} n={m['n']}", flush=True)
202
+
203
+ print(json.dumps(results, indent=2))
204
+
205
+ if not args.skip_spot_check:
206
+ print("\n=== Spot check: base model vs. LoRA-adapted, Code2LoRA paper facts ===", flush=True)
207
+ paper_doc = next((d for d in all_docs if d.doc_id == "code2lora_paper"), None)
208
+ if paper_doc is None:
209
+ print(" [skip] code2lora_paper doc not found in embeddings", flush=True)
210
+ else:
211
+ ctx = torch.from_numpy(paper_doc.doc_embedding).to(device).unsqueeze(0)
212
+ head_out = head(ctx)
213
+ for q, gold in SPOT_CHECK_QUESTIONS:
214
+ prefix = f"Q: {q}\nA:"
215
+ # base: zero out LoRA (A=B=None) by re-wrapping without injection
216
+ for sp in specs:
217
+ named = dict(base_model.named_modules())
218
+ named[sp.full_name].A = None
219
+ named[sp.full_name].B = None
220
+ base_pred = generate(base_model, tokenizer, prefix, device)
221
+ inject_lora_weights(base_model, specs, head_out, batch_index=0)
222
+ adapted_pred = generate(base_model, tokenizer, prefix, device)
223
+ print(f"Q: {q}")
224
+ print(f" gold: {gold}")
225
+ print(f" base: {base_pred!r}")
226
+ print(f" adapted: {adapted_pred!r}")
227
+ print()
228
+
229
+
230
+ if __name__ == "__main__":
231
+ main()
scripts/generate_commitpack_qa.py ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Breadth generator: judgment QA from CommitPackFT commits across THOUSANDS
3
+ of DISTINCT repos (25k distinct repos in the python shard alone).
4
+
5
+ Complements generate_techlead_qa.py (SWE-bench), which is deep but spans only
6
+ ~12 repos. For a HYPERNETWORK, distinct-repo count is the currency of
7
+ generalization -- so this takes ~1 commit per NEW repo to maximize breadth,
8
+ not many commits of the same repo.
9
+
10
+ Commit-scope judgment aspects (a single small commit rarely shows whole-system
11
+ architecture, so we skip that): why / conventions / contracts / impact.
12
+ Same Tier-A/B discipline: short judgment answers, no exact file/line lists.
13
+ gemini-3.6-flash reasoning is mandatory -> generous max_tokens.
14
+
15
+ Usage:
16
+ python scripts/generate_commitpack_qa.py --limit 3
17
+ python scripts/generate_commitpack_qa.py --max-repos 2500 --per-repo 1
18
+ """
19
+ from __future__ import annotations
20
+ import argparse, hashlib, json, os, re, sys, time
21
+ from pathlib import Path
22
+ from typing import Dict, List
23
+ from openai import OpenAI
24
+
25
+ HERE = Path(__file__).resolve().parent; REPO_ROOT = HERE.parent
26
+ sys.path.insert(0, str(REPO_ROOT))
27
+ from memory_lora.data_paths import QNA_DIR, DOCS_DIR, CACHE_DIR, ensure_dirs # noqa: E402
28
+
29
+ def _load_dotenv(p: Path):
30
+ if p.exists():
31
+ for line in p.read_text().splitlines():
32
+ if "=" in line and not line.strip().startswith("#"):
33
+ k, v = line.split("=", 1); os.environ.setdefault(k.strip(), v.strip())
34
+ _load_dotenv(REPO_ROOT / ".env")
35
+
36
+ MODEL = "google/gemini-3.6-flash"
37
+ BASE_URL = "https://openrouter.ai/api/v1"
38
+ SHARD = REPO_ROOT / "data" / "commitpack" / "multilang_commits.jsonl"
39
+
40
+ SYSTEM = (
41
+ "You are a staff engineer writing onboarding Q&A about a single real commit. "
42
+ "Given the commit message and the before/after file contents, produce a JSON "
43
+ "array of 3-4 objects with keys 'aspect','question','answer'. aspect in: "
44
+ "why, conventions, contracts, impact. Rules: (1) test JUDGMENT/understanding, "
45
+ "not trivia. (2) answers SHORT -- one phrase/sentence, no file paths or line "
46
+ "numbers. (3) 'why' = rationale/trade-off; 'impact' = the KIND of behavior/"
47
+ "contract affected, not a file list; 'conventions' = the idiom/style this "
48
+ "change follows. (4) ground answers in the actual change; invent nothing. "
49
+ "Output ONLY the JSON array."
50
+ )
51
+
52
+ def cache_key(*p): return hashlib.sha256("||".join(p).encode()).hexdigest()[:24]
53
+
54
+ def gen_qa(client, ctx, cache_dir, retries=4) -> List[Dict]:
55
+ cf = cache_dir / f"cpqa_{cache_key(MODEL, ctx)}.json"
56
+ if cf.exists():
57
+ raw = cf.read_text()
58
+ else:
59
+ last = None
60
+ for a in range(retries):
61
+ try:
62
+ r = client.chat.completions.create(model=MODEL,
63
+ messages=[{"role": "system", "content": SYSTEM},
64
+ {"role": "user", "content": ctx}],
65
+ max_tokens=3000, temperature=0.6)
66
+ raw = r.choices[0].message.content or ""; cf.write_text(raw); break
67
+ except Exception as e: # noqa: BLE001
68
+ last = e; time.sleep(2 ** a)
69
+ else:
70
+ return []
71
+ m = re.search(r"\[.*\]", raw, re.DOTALL)
72
+ if not m: return []
73
+ try: items = json.loads(m.group(0))
74
+ except json.JSONDecodeError: return []
75
+ out = []
76
+ for it in items:
77
+ q = (it.get("question") or "").strip(); a = (it.get("answer") or "").strip()
78
+ asp = (it.get("aspect") or "general").strip()
79
+ if q and a and len(a) < 240: out.append({"aspect": asp, "question": q, "answer": a})
80
+ return out
81
+
82
+ def build_ctx(d) -> str:
83
+ def clip(s, n): return (s or "")[:n]
84
+ return (f"REPO: {d['repos'].split(',')[0]} FILE: {d.get('new_file','')}\n"
85
+ f"COMMIT: {clip(d.get('subject'),120)}\n{clip(d.get('message'),500)}\n\n"
86
+ f"BEFORE:\n{clip(d.get('old_contents'),1800)}\n\n"
87
+ f"AFTER:\n{clip(d.get('new_contents'),1800)}")
88
+
89
+ def main():
90
+ import threading
91
+ from concurrent.futures import ThreadPoolExecutor, as_completed
92
+ ap = argparse.ArgumentParser()
93
+ ap.add_argument("--max-repos", type=int, default=2500)
94
+ ap.add_argument("--per-repo", type=int, default=1)
95
+ ap.add_argument("--limit", type=int, default=0)
96
+ ap.add_argument("--model", default=MODEL)
97
+ ap.add_argument("--workers", type=int, default=10,
98
+ help="Concurrent OpenRouter requests. Sequential gen was "
99
+ "~10x too slow for 3k+ repos; the API handles "
100
+ "concurrency fine and the per-prompt cache keeps it "
101
+ "idempotent.")
102
+ args = ap.parse_args()
103
+ globals()["MODEL"] = args.model
104
+ ensure_dirs()
105
+ key = os.environ.get("OPENROUTER_API_KEY")
106
+ if not key: raise SystemExit("OPENROUTER_API_KEY not set")
107
+ client = OpenAI(base_url=BASE_URL, api_key=key)
108
+
109
+ target = args.limit if args.limit else args.max_repos
110
+ # select one commit per distinct repo (breadth), up to target
111
+ seen: Dict[str, int] = {}
112
+ tasks = []
113
+ for line in open(SHARD):
114
+ if len(tasks) >= target: break
115
+ try: d = json.loads(line)
116
+ except json.JSONDecodeError: continue
117
+ repo = d["repos"].split(",")[0]
118
+ if seen.get(repo, 0) >= args.per_repo: continue
119
+ seen[repo] = seen.get(repo, 0) + 1
120
+ tasks.append(d)
121
+
122
+ qna_f = (QNA_DIR / "techlead_qa_commitpack.jsonl").open("a")
123
+ src_f = (DOCS_DIR / "techlead_sources_commitpack.jsonl").open("a")
124
+ lock = threading.Lock()
125
+ n_docs = [0]; n_qa = [0]; t0 = time.time()
126
+
127
+ def work(d):
128
+ repo = d["repos"].split(",")[0]
129
+ qas = gen_qa(client, build_ctx(d), CACHE_DIR)
130
+ if not qas: return
131
+ doc_id = f"{repo}@{d['commit'][:10]}"
132
+ with lock:
133
+ src_f.write(json.dumps({"doc_id": doc_id, "repo": repo, "base_commit": d["commit"],
134
+ "context": build_ctx(d), "source": "commitpackft", "lang": d.get("lang","python")}) + "\n")
135
+ for qa in qas:
136
+ qna_f.write(json.dumps({"doc_id": doc_id, "doc_version": d["commit"],
137
+ "split": "train", "qna_split": "train", "aspect": qa["aspect"],
138
+ "question": qa["question"], "prefix": f"Q: {qa['question']}\nA:",
139
+ "target": " " + qa["answer"], "lang": d.get("lang","python")}) + "\n")
140
+ n_qa[0] += 1
141
+ n_docs[0] += 1
142
+ if n_docs[0] % 50 == 0:
143
+ rate = n_docs[0] / max(1e-9, (time.time() - t0) / 60)
144
+ print(f" {n_docs[0]} repos, {n_qa[0]} QA ({rate:.1f} repo/min)", flush=True)
145
+
146
+ with ThreadPoolExecutor(max_workers=args.workers) as ex:
147
+ for _ in as_completed([ex.submit(work, d) for d in tasks]):
148
+ pass
149
+ qna_f.close(); src_f.close()
150
+ print(f"\nDone. {n_docs[0]} DISTINCT repos -> {n_qa[0]} judgment-QA pairs.", flush=True)
151
+
152
+ if __name__ == "__main__":
153
+ main()
scripts/generate_repo_scoped_qa.py ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Generate REPO-SCOPED judgment QA from the SAME 6 views that
3
+ build_repo_multiview.py embedded -- so target scope matches input scope
4
+ (a repo-level embedding must be paired with repo-level questions, not
5
+ commit-scoped ones). Reads data/docs/multiview_sources.jsonl (per-repo
6
+ view_text) and writes data/qna/repo_scoped_qa.jsonl keyed by the same
7
+ doc_id (= repo name).
8
+
9
+ gemini-3.6-flash: reasoning mandatory -> generous max_tokens.
10
+ Tier-A/B discipline: judgment answers, short, no exact file/line lists.
11
+
12
+ Usage:
13
+ python scripts/generate_repo_scoped_qa.py --limit 3
14
+ python scripts/generate_repo_scoped_qa.py
15
+ """
16
+ from __future__ import annotations
17
+ import argparse, hashlib, json, os, re, sys, time
18
+ from pathlib import Path
19
+ from typing import Dict, List
20
+ from openai import OpenAI
21
+
22
+ HERE = Path(__file__).resolve().parent; REPO_ROOT = HERE.parent
23
+ sys.path.insert(0, str(REPO_ROOT))
24
+ from memory_lora.data_paths import QNA_DIR, DOCS_DIR, CACHE_DIR, ensure_dirs # noqa: E402
25
+
26
+ def _load_dotenv(p: Path):
27
+ if p.exists():
28
+ for line in p.read_text().splitlines():
29
+ if "=" in line and not line.strip().startswith("#"):
30
+ k, v = line.split("=", 1); os.environ.setdefault(k.strip(), v.strip())
31
+ _load_dotenv(REPO_ROOT / ".env")
32
+ MODEL = "google/gemini-3.6-flash"; BASE_URL = "https://openrouter.ai/api/v1"
33
+
34
+ SYSTEM = (
35
+ "You are a 20-year tech lead writing onboarding Q&A for a NEW engineer joining "
36
+ "a repository. You are given 6 views of the repo: its call/import graph, "
37
+ "architecture (readme/tree), git history, test contracts, code conventions, "
38
+ "and ops/build config. Produce a JSON array of 8-12 objects with keys "
39
+ "'aspect','question','answer'. aspect in: architecture, data_flow, why, "
40
+ "contracts, conventions, impact, ops. Rules: (1) questions are REPO-LEVEL and "
41
+ "test JUDGMENT a senior would have ('what layer owns X', 'what convention does "
42
+ "this repo use for Y', 'how does data flow through Z', 'why is this structured "
43
+ "this way'), NOT trivia about one commit. (2) answers SHORT -- one phrase or "
44
+ "sentence, copyable, NO file-path or line-number lists. (3) 'impact' = the KIND "
45
+ "of thing that breaks/changes, not an exact file enumeration. (4) ground every "
46
+ "answer in the provided views; invent nothing. Output ONLY the JSON array."
47
+ )
48
+
49
+ def ckey(*p): return hashlib.sha256("||".join(p).encode()).hexdigest()[:24]
50
+
51
+ def gen(client, ctx, cache_dir, retries=4) -> List[Dict]:
52
+ cf = cache_dir / f"rsqa_{ckey(MODEL, ctx)}.json"
53
+ if cf.exists():
54
+ raw = cf.read_text()
55
+ else:
56
+ last = None
57
+ for a in range(retries):
58
+ try:
59
+ r = client.chat.completions.create(model=MODEL,
60
+ messages=[{"role": "system", "content": SYSTEM}, {"role": "user", "content": ctx}],
61
+ max_tokens=4000, temperature=0.6)
62
+ raw = r.choices[0].message.content or ""; cf.write_text(raw); break
63
+ except Exception as e: # noqa: BLE001
64
+ last = e; time.sleep(2 ** a)
65
+ else:
66
+ return []
67
+ m = re.search(r"\[.*\]", raw, re.DOTALL)
68
+ if not m: return []
69
+ try: items = json.loads(m.group(0))
70
+ except json.JSONDecodeError: return []
71
+ out = []
72
+ for it in items:
73
+ q = (it.get("question") or "").strip(); a = (it.get("answer") or "").strip()
74
+ asp = (it.get("aspect") or "general").strip()
75
+ if q and a and len(a) < 240: out.append({"aspect": asp, "question": q, "answer": a})
76
+ return out
77
+
78
+ def build_ctx(repo: str, vt: Dict[str, str]) -> str:
79
+ parts = [f"REPOSITORY: {repo}\n"]
80
+ for k in ["v_arch", "v_graph", "v_history", "v_contracts", "v_conventions", "v_ops"]:
81
+ parts.append(f"=== {k} ===\n{vt.get(k,'')}\n")
82
+ return "\n".join(parts)
83
+
84
+ def main():
85
+ import threading
86
+ from concurrent.futures import ThreadPoolExecutor, as_completed
87
+ ap = argparse.ArgumentParser()
88
+ ap.add_argument("--sources", default=str(DOCS_DIR / "multiview_sources.jsonl"))
89
+ ap.add_argument("--limit", type=int, default=0)
90
+ ap.add_argument("--model", default=MODEL)
91
+ ap.add_argument("--workers", type=int, default=10)
92
+ args = ap.parse_args()
93
+ globals()["MODEL"] = args.model
94
+ ensure_dirs()
95
+ key = os.environ.get("OPENROUTER_API_KEY")
96
+ if not key: raise SystemExit("OPENROUTER_API_KEY not set")
97
+ client = OpenAI(base_url=BASE_URL, api_key=key)
98
+
99
+ src = [json.loads(l) for l in open(args.sources)]
100
+ if args.limit: src = src[: args.limit]
101
+ outp = QNA_DIR / "repo_scoped_qa.jsonl"
102
+ done = set()
103
+ if outp.exists():
104
+ done = {json.loads(l)["doc_id"] for l in open(outp)}
105
+ todo = [r for r in src if r["doc_id"] not in done]
106
+ out_f = outp.open("a")
107
+ lock = threading.Lock()
108
+ n_docs = [0]; n_qa = [0]; t0 = time.time()
109
+
110
+ def work(row):
111
+ doc_id = row["doc_id"]
112
+ qas = gen(client, build_ctx(row["repo"], row["view_text"]), CACHE_DIR)
113
+ if not qas: return
114
+ with lock:
115
+ for qa in qas:
116
+ out_f.write(json.dumps({"doc_id": doc_id, "doc_version": "head",
117
+ "split": "train", "qna_split": "train", "aspect": qa["aspect"],
118
+ "question": qa["question"], "prefix": f"Q: {qa['question']}\nA:",
119
+ "target": " " + qa["answer"], "lang": row.get("lang", "unknown")}) + "\n")
120
+ n_qa[0] += 1
121
+ n_docs[0] += 1
122
+ if n_docs[0] % 25 == 0:
123
+ print(f" {n_docs[0]}/{len(todo)} repos, {n_qa[0]} QA "
124
+ f"({n_docs[0]/max(1e-9,(time.time()-t0)/60):.1f}/min)", flush=True)
125
+
126
+ with ThreadPoolExecutor(max_workers=args.workers) as ex:
127
+ for _ in as_completed([ex.submit(work, r) for r in todo]):
128
+ pass
129
+ out_f.close()
130
+ print(f"\nDone. {n_docs[0]} repos -> {n_qa[0]} repo-scoped judgment QA.", flush=True)
131
+
132
+ if __name__ == "__main__":
133
+ main()
scripts/generate_synthetic_dataset.py ADDED
@@ -0,0 +1,545 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Generate the Memory-LoRA training corpus via OpenRouter.
3
+
4
+ Produces two local parquet-backed artifacts under ``data/``:
5
+
6
+ data/docs/documents.jsonl -- one row per document (id, category, topic,
7
+ cross-corpus split, list of (section, text))
8
+ data/qna/qna.jsonl -- one row per recall QA pair (doc_id, split,
9
+ qna_split, question, prefix, target)
10
+
11
+ Four document categories, all seeded to contain specific, checkable facts
12
+ (numbers, names, claims) so recall is gradeable by exact-match, mirroring
13
+ Code2LoRA's assertion-completion targets:
14
+
15
+ paper -- the REAL Code2LoRA paper, chunked into sections
16
+ (not synthetic -- hand-authored below from the
17
+ paper we already read in full).
18
+ coding_agent_harness -- synthetic docs about capabilities that help coding
19
+ agents / CLI tools (Claude Code, Codex, etc.) handle
20
+ large codebases: context injection, repo indexing,
21
+ diffing, static analysis, self-improvement loops.
22
+ agile_pm -- synthetic docs about agile project tracking: Jira
23
+ ticket lifecycles, sprints, story points, velocity,
24
+ epics, standups, retrospectives, burndown.
25
+ general -- broad diverse synthetic fact-sheets, needed so the
26
+ hypernetwork's document->LoRA mapping generalizes
27
+ (breadth requirement, same reason Code2LoRA needed
28
+ 400+ repos rather than 1).
29
+
30
+ OpenRouter is OpenAI-API compatible -- plain ``openai`` client,
31
+ base_url=https://openrouter.ai/api/v1. Key read from OPENROUTER_API_KEY
32
+ (loaded from a local .env, never hardcoded/committed).
33
+
34
+ Usage:
35
+ python scripts/generate_synthetic_dataset.py --limit 3 # smoke test
36
+ python scripts/generate_synthetic_dataset.py --n-per-category 60
37
+ """
38
+
39
+ from __future__ import annotations
40
+
41
+ import argparse
42
+ import hashlib
43
+ import json
44
+ import os
45
+ import random
46
+ import re
47
+ import sys
48
+ import time
49
+ from pathlib import Path
50
+ from typing import Any, Dict, List, Optional
51
+
52
+ from openai import OpenAI
53
+
54
+ HERE = Path(__file__).resolve().parent
55
+ REPO_ROOT = HERE.parent
56
+ sys.path.insert(0, str(REPO_ROOT))
57
+ from memory_lora.data_paths import DOCS_DIR, QNA_DIR, CACHE_DIR, ensure_dirs # noqa: E402
58
+
59
+
60
+ def _load_dotenv(path: Path) -> None:
61
+ if not path.exists():
62
+ return
63
+ for line in path.read_text().splitlines():
64
+ line = line.strip()
65
+ if not line or line.startswith("#") or "=" not in line:
66
+ continue
67
+ k, v = line.split("=", 1)
68
+ os.environ.setdefault(k.strip(), v.strip())
69
+
70
+
71
+ _load_dotenv(REPO_ROOT / ".env")
72
+
73
+ DEFAULT_GEN_MODEL = "qwen/qwen-2.5-7b-instruct"
74
+ OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1"
75
+
76
+
77
+ # ---------------------------------------------------------------------------
78
+ # Cache-wrapped OpenRouter call
79
+ # ---------------------------------------------------------------------------
80
+
81
+ def _cache_key(model: str, messages: List[Dict[str, str]], **kwargs) -> str:
82
+ payload = json.dumps({"model": model, "messages": messages, **kwargs},
83
+ sort_keys=True)
84
+ return hashlib.sha256(payload.encode()).hexdigest()[:24]
85
+
86
+
87
+ class CachedClient:
88
+ def __init__(self, client: OpenAI, cache_dir: Path):
89
+ self.client = client
90
+ self.cache_dir = cache_dir
91
+
92
+ def chat(self, model: str, messages: List[Dict[str, str]],
93
+ temperature: float = 0.9, max_tokens: int = 2000,
94
+ retries: int = 4) -> str:
95
+ key = _cache_key(model, messages, temperature=temperature,
96
+ max_tokens=max_tokens)
97
+ cache_file = self.cache_dir / f"{key}.txt"
98
+ if cache_file.exists():
99
+ return cache_file.read_text()
100
+ last_err: Optional[Exception] = None
101
+ for attempt in range(retries):
102
+ try:
103
+ resp = self.client.chat.completions.create(
104
+ model=model, messages=messages,
105
+ temperature=temperature, max_tokens=max_tokens,
106
+ )
107
+ text = resp.choices[0].message.content or ""
108
+ cache_file.write_text(text)
109
+ return text
110
+ except Exception as e: # noqa: BLE001
111
+ last_err = e
112
+ wait = 2 ** attempt
113
+ print(f" [warn] OpenRouter call failed ({e}); retry in {wait}s",
114
+ flush=True)
115
+ time.sleep(wait)
116
+ raise RuntimeError(f"OpenRouter call failed after {retries} retries: {last_err}")
117
+
118
+
119
+ # ---------------------------------------------------------------------------
120
+ # Topic seeds per category (kept diverse -> the hypernetwork sees breadth)
121
+ # ---------------------------------------------------------------------------
122
+
123
+ CODING_AGENT_TOPICS = [
124
+ "repository-level context injection strategies for LLM coding agents",
125
+ "incremental static analysis caching for large monorepos",
126
+ "test-impact analysis to select which tests to rerun after a diff",
127
+ "dependency graph indexing for cross-file code navigation",
128
+ "safe automated refactoring patterns for renaming across a codebase",
129
+ "context window budget management when an agent reads many files",
130
+ "self-improvement loops where a coding agent revises its own tool use",
131
+ "diffing and patch-application strategies for multi-file edits",
132
+ "detecting and avoiding regressions when an agent edits shared utilities",
133
+ "code search ranking heuristics for retrieval-augmented coding agents",
134
+ "sandboxing and permission models for autonomous coding agents",
135
+ "long-horizon planning for agents building complex multi-module programs",
136
+ "memory architectures that let an agent recall project conventions",
137
+ "strategies for agents to keep a mental model of a large codebase in sync",
138
+ "CLI tool design patterns for developer-facing coding agents",
139
+ "evaluating coding agent reliability on multi-step programming tasks",
140
+ "handling build system and dependency resolution errors autonomously",
141
+ "techniques for agents to summarize large pull requests for review",
142
+ "version-control-aware agent workflows (branches, rebases, conflicts)",
143
+ "strategies for agents to write and maintain their own regression tests",
144
+ ]
145
+
146
+ AGILE_PM_TOPICS = [
147
+ "Jira ticket lifecycle states and transition rules",
148
+ "sprint planning and story point estimation techniques",
149
+ "velocity tracking and forecasting sprint capacity",
150
+ "epic and subtask hierarchy conventions in agile tracking tools",
151
+ "daily standup meeting structure and anti-patterns",
152
+ "sprint retrospective formats and action item follow-through",
153
+ "burndown and burnup chart interpretation",
154
+ "backlog grooming and prioritization frameworks (MoSCoW, WSJF)",
155
+ "definition of done and acceptance criteria best practices",
156
+ "kanban WIP limits and flow efficiency metrics",
157
+ "cross-team dependency tracking in scaled agile (SAFe, LeSS)",
158
+ "bug triage severity/priority labeling conventions",
159
+ "release planning and versioning cadences",
160
+ "stakeholder reporting cadences and status update formats",
161
+ "agile ceremonies for distributed/remote teams",
162
+ ]
163
+
164
+ PROJECT_STATUS_TOPICS = [
165
+ "a web app team's sprint status: open tickets, in-progress work, recent commits",
166
+ "a data pipeline team's current sprint: blocked tickets, recent diffs, on-call rotation",
167
+ "a mobile app team's release cycle: feature tickets, QA status, code review queue",
168
+ "an API service team's incident + sprint status: hotfix tickets, recent deploys",
169
+ "an ML training infra team's sprint: experiment tickets, recent config diffs",
170
+ "a platform team's migration project: tracked subtasks, rollout percentage, blockers",
171
+ "a devtools team's backlog grooming outcome: prioritized tickets, recent PRs merged",
172
+ "a security team's remediation sprint: CVE tickets, patch status, recent commits",
173
+ "a frontend team's design-system rollout: component tickets, adoption tracking",
174
+ "a backend team's database migration sprint: schema tickets, rollback plan, diffs",
175
+ ]
176
+
177
+ PROJECT_STATUS_SYSTEM = (
178
+ "You write a realistic internal project-status snapshot for a software "
179
+ "team, combining a Jira-style ticket board with recent code activity. "
180
+ "Invent a plausible project/repo name, then include: (1) 6-10 tickets, "
181
+ "each with a ticket key (e.g. PROJ-1234), status (To Do/In Progress/In "
182
+ "Review/Done/Blocked), assignee name, story points, and a one-line "
183
+ "description; (2) a sprint summary (sprint number, dates, velocity, "
184
+ "burndown status); (3) a 'recent changes' section describing 2-4 "
185
+ "specific code changes (file names, what changed, why) as if summarizing "
186
+ "recent commits/diffs; (4) any current blockers or risks. Every fact "
187
+ "(ticket key, status, assignee, points, sprint number, file name) must "
188
+ "be specific and consistent so it can be tested for recall. 400-700 "
189
+ "words. No markdown headers, structured prose with clear labels."
190
+ )
191
+
192
+
193
+ def gen_project_status_document(client: CachedClient, model: str, topic: str) -> str:
194
+ prompt = f"Write a project-status snapshot for: {topic}."
195
+ return client.chat(
196
+ model=model,
197
+ messages=[
198
+ {"role": "system", "content": PROJECT_STATUS_SYSTEM},
199
+ {"role": "user", "content": prompt},
200
+ ],
201
+ temperature=0.9,
202
+ max_tokens=1400,
203
+ )
204
+
205
+
206
+ GENERAL_TOPICS = [
207
+ "the history and mechanics of a fictional national park's geology",
208
+ "the biology of a deep-sea bioluminescent organism",
209
+ "the engineering of a suspension bridge's cable system",
210
+ "the brewing process and quality control of specialty coffee",
211
+ "the orbital mechanics of a hypothetical exoplanet system",
212
+ "the supply chain logistics of a regional produce cooperative",
213
+ "the architecture of a public transit signaling system",
214
+ "the culinary traditions of a fictional coastal fishing village",
215
+ "the manufacturing process of a specific alloy used in aerospace",
216
+ "the ecology of a wetland restoration project",
217
+ "the governance structure of a municipal water utility",
218
+ "the training regimen of competitive long-distance cyclists",
219
+ "the archival practices of a rare-book conservation lab",
220
+ "the acoustics engineering of a concert hall renovation",
221
+ "the logistics of a regional disaster-relief supply network",
222
+ "the taxonomy and care requirements of a rare orchid genus",
223
+ "the operations of a small-batch letterpress printing studio",
224
+ "the hydrology of an urban stormwater management system",
225
+ "the production pipeline of a stop-motion animation studio",
226
+ "the maintenance schedule of a commercial wind turbine farm",
227
+ ]
228
+
229
+ DOC_GEN_SYSTEM = (
230
+ "You write dense, factual reference documents. Every document must contain "
231
+ "15-30 SPECIFIC, VERIFIABLE facts: exact numbers, named entities, precise "
232
+ "claims, thresholds, or procedures. Avoid vague generalities. Write "
233
+ "300-800 words. Do not use markdown headers; write flowing prose "
234
+ "paragraphs. Invent plausible specifics (names, numbers, dates) when the "
235
+ "topic is fictional/hypothetical -- consistency within the document "
236
+ "matters more than real-world accuracy."
237
+ )
238
+
239
+ QA_GEN_SYSTEM = (
240
+ "You extract recall test questions from a reference document. Given the "
241
+ "document, produce a JSON array of 15-25 objects, each with keys "
242
+ "'question' and 'answer'. Each question must test recall of ONE specific "
243
+ "fact stated in the document (a number, name, threshold, or precise "
244
+ "claim). The answer must be SHORT (1-8 words, ideally a number, name, or "
245
+ "short phrase) and must be copyable verbatim or near-verbatim from the "
246
+ "document. Do not ask yes/no questions. Do not ask questions requiring "
247
+ "reasoning beyond direct recall. Output ONLY the JSON array, no prose."
248
+ )
249
+
250
+
251
+ def gen_document(client: CachedClient, model: str, category: str, topic: str) -> str:
252
+ prompt = (
253
+ f"Write a reference document about: {topic}.\n"
254
+ f"Category: {category}."
255
+ )
256
+ return client.chat(
257
+ model=model,
258
+ messages=[
259
+ {"role": "system", "content": DOC_GEN_SYSTEM},
260
+ {"role": "user", "content": prompt},
261
+ ],
262
+ temperature=0.9,
263
+ max_tokens=1200,
264
+ )
265
+
266
+
267
+ def gen_qna(client: CachedClient, model: str, doc_text: str) -> List[Dict[str, str]]:
268
+ raw = client.chat(
269
+ model=model,
270
+ messages=[
271
+ {"role": "system", "content": QA_GEN_SYSTEM},
272
+ {"role": "user", "content": doc_text},
273
+ ],
274
+ temperature=0.3,
275
+ max_tokens=2000,
276
+ )
277
+ match = re.search(r"\[.*\]", raw, re.DOTALL)
278
+ if not match:
279
+ return []
280
+ try:
281
+ items = json.loads(match.group(0))
282
+ except json.JSONDecodeError:
283
+ return []
284
+ out = []
285
+ for it in items:
286
+ q = (it.get("question") or "").strip()
287
+ a = (it.get("answer") or "").strip()
288
+ if q and a and len(a) < 200:
289
+ out.append({"question": q, "answer": a})
290
+ return out
291
+
292
+
293
+ # ---------------------------------------------------------------------------
294
+ # The Code2LoRA paper -- real document, hand-chunked into sections (from the
295
+ # paper we already read in full; not regenerated by an LLM).
296
+ # ---------------------------------------------------------------------------
297
+
298
+ def code2lora_paper_sections() -> List[Dict[str, str]]:
299
+ return [
300
+ {"name": "abstract", "text": (
301
+ "Code2LoRA is a hypernetwork framework that generates repository-"
302
+ "specific LoRA adapters, effectively injecting repository "
303
+ "knowledge with zero inference-time token overhead. Code2LoRA "
304
+ "supports two usage scenarios: Code2LoRA-Static converts a "
305
+ "single repository snapshot into an adapter; Code2LoRA-Evo "
306
+ "maintains an adapter backed by a GRU hidden state updated per "
307
+ "code diff. The authors build RepoPeftBench, a benchmark of 604 "
308
+ "Python repositories with two tracks: a static track with 40K "
309
+ "training and 12K test assertion-completion tasks, and an "
310
+ "evolution track with 215K commit-derived training and 87K "
311
+ "commit-derived test tasks. On the static track, Code2LoRA-"
312
+ "Static achieves 63.8% cross-repo and 66.2% in-repo exact match, "
313
+ "matching the per-repository LoRA upper bound; on the evolution "
314
+ "track, Code2LoRA-Evo achieves 60.3% cross-repo exact match, "
315
+ "+5.2 percentage points over a single shared LoRA."
316
+ )},
317
+ {"name": "method_architecture", "text": (
318
+ "Code2LoRA has three components: a shared repository encoder "
319
+ "that maps repository-level context to dense embeddings, a "
320
+ "hypernetwork that maps those embeddings to LoRA weights, and a "
321
+ "base LLM that receives the generated adapter. Only the "
322
+ "hypernetwork is trained. The repository encoder uses a frozen "
323
+ "Qwen3-Embedding-0.6B model: each file is divided into 4096-"
324
+ "token chunks with 512-token overlap, embedded, and mean-pooled "
325
+ "to produce a file vector of dimension 1024. The repository "
326
+ "embedding is the concatenation of a weighted mean and a max "
327
+ "pool of file vectors, giving a 2048-dimensional vector. "
328
+ "Code2LoRA-Static's hypernetwork has a 2-layer MLP trunk with "
329
+ "GELU activation, hidden dimension 1024, followed by dedicated "
330
+ "output heads per module type. LoRA matrices use rank r=16 and "
331
+ "alpha=32, targeting seven module types (q_proj, k_proj, "
332
+ "v_proj, o_proj, gate_proj, up_proj, down_proj) shared across "
333
+ "all 28 transformer layers of the base model. Code2LoRA-Static "
334
+ "has approximately 720 million trainable parameters. Code2LoRA-"
335
+ "Evo adds a 1-layer GRU with hidden size 2048 that aggregates "
336
+ "sequential diff embeddings into a hidden state, which "
337
+ "substitutes for the static embedding in the same shared head; "
338
+ "Code2LoRA-Evo has approximately 745 million trainable "
339
+ "parameters, using truncated backpropagation through time with "
340
+ "a window of K=16 steps."
341
+ )},
342
+ {"name": "benchmark_repopeftbench", "text": (
343
+ "RepoPeftBench comprises 604 Python repositories drawn from "
344
+ "GitHub: 512 in-distribution repositories (requiring at least "
345
+ "300 stars) and a 92-repository temporal out-of-distribution "
346
+ "holdout created strictly after the 2025-04-01 scrape cutoff. "
347
+ "The in-distribution set is partitioned into cross-repo (103 "
348
+ "held-out repositories: 51 validation, 52 test) and in-repo "
349
+ "(409 training repositories) splits. The task is assertion "
350
+ "completion: given a structured prefix from a test file "
351
+ "(imports, enclosing class, helper methods, test body up to the "
352
+ "assertion), the model predicts the expected value of the "
353
+ "assertion. The static track draws 39,612 training and 11,636 "
354
+ "test tasks from repository snapshots. The evolution track "
355
+ "replays commit history, yielding 215,129 training and 86,793 "
356
+ "test tasks derived from commits. Evaluation metrics are Exact "
357
+ "Match (EM), Edit Similarity, and CodeBLEU. The base LLM used "
358
+ "in all experiments is Qwen2.5-Coder-1.5B, loaded in bfloat16, "
359
+ "trained on a single H100 80GB GPU using the TRL library."
360
+ )},
361
+ {"name": "results_static_track", "text": (
362
+ "On RepoPeftBench's static track, Code2LoRA-Static achieves "
363
+ "63.8% cross-repo exact match, 9.9 percentage points above the "
364
+ "strongest baseline (full fine-tuning plus RAG, at 53.9%). "
365
+ "Other baselines score lower: RAG with k=3 reaches 39.7% EM, "
366
+ "Dependency-Resolved Context reaches 48.2% EM, full fine-tuning "
367
+ "alone reaches 51.4% EM, and a single shared LoRA reaches 47.4% "
368
+ "EM. On in-repo evaluation, Code2LoRA-Static reaches 66.2% EM, "
369
+ "matching the per-repository LoRA upper bound of 64.0% EM "
370
+ "without any per-repository training. A strengthened Text2LoRA "
371
+ "baseline, matched on input modality and target-module "
372
+ "coverage, reaches only 45.8% EM on cross-repo, isolating the "
373
+ "Text2LoRA hypernetwork head itself as the bottleneck."
374
+ )},
375
+ {"name": "results_evolution_track", "text": (
376
+ "On the evolution track, which evaluates on commit-derived "
377
+ "prefixes, Code2LoRA-Evo is the strongest method on both "
378
+ "splits: 60.3% cross-repo EM and 64.5% in-repo EM, a gain of "
379
+ "5.2 percentage points over a single shared LoRA on cross-repo. "
380
+ "Code2LoRA-Evo's in-repo EM of 64.5% exceeds the per-repository "
381
+ "LoRA upper bound of 64.2% without any per-repository training. "
382
+ "Code2LoRA-Static, evaluated on the same commit-derived inputs "
383
+ "as a within-framework reference, drops to 55.7% cross-repo EM "
384
+ "and 60.6% in-repo EM, markedly below its static-track "
385
+ "performance, showing that snapshot-based adaptation goes "
386
+ "stale as a repository accumulates commits. On the 92-"
387
+ "repository temporal out-of-distribution holdout, Code2LoRA-"
388
+ "Evo achieves the highest exact match at 74.1%, ahead of "
389
+ "Code2LoRA-Static at 72.2% and a single shared LoRA at 72.3%."
390
+ )},
391
+ {"name": "efficiency", "text": (
392
+ "Code2LoRA-Static and Code2LoRA-Evo generate a repository-"
393
+ "specific adapter in under 10 milliseconds per repository with "
394
+ "zero extra inference tokens, versus approximately 1,500 extra "
395
+ "tokens per query for RAG with k=3, and approximately 500 to "
396
+ "2,000 extra tokens per query for Dependency-Resolved Context. "
397
+ "Full fine-tuning requires about 4 hours of training and adds "
398
+ "3.1 gigabytes of storage per repository; per-repository LoRA "
399
+ "requires about 5 minutes of training and 32 megabytes of "
400
+ "storage per repository. In contrast, Code2LoRA-Static's "
401
+ "hypernetwork adds a fixed 679 megabytes of storage shared "
402
+ "across all repositories, and Code2LoRA-Evo adds 65 megabytes, "
403
+ "independent of how many repositories are served."
404
+ )},
405
+ {"name": "limitations", "text": (
406
+ "The Code2LoRA paper's limitations section notes the evaluation "
407
+ "is restricted to Python repositories, a single frozen backbone "
408
+ "(Qwen2.5-Coder-1.5B), and one downstream task (assertion "
409
+ "completion). The reported 74.1% out-of-distribution exact "
410
+ "match may be partially inflated because assertion targets in "
411
+ "the post-cutoff OOD repositories are systematically shorter "
412
+ "(median 7 characters) than in the cross-repo and in-repo test "
413
+ "sets (median 12-13 characters). The LoRA-generation "
414
+ "hypernetwork dominates the trainable parameter count -- "
415
+ "approximately 720 million for Code2LoRA-Static and 745 "
416
+ "million for Code2LoRA-Evo -- so the evolution-track finding "
417
+ "is most directly supported at the 1.5-billion-parameter "
418
+ "backbone scale."
419
+ )},
420
+ ]
421
+
422
+
423
+ # ---------------------------------------------------------------------------
424
+ # Splits + orchestration
425
+ # ---------------------------------------------------------------------------
426
+
427
+ def assign_cross_corpus_split(rng: random.Random) -> str:
428
+ r = rng.random()
429
+ if r < 0.8:
430
+ return "train"
431
+ if r < 0.9:
432
+ return "cr_val"
433
+ return "cr_test"
434
+
435
+
436
+ def main() -> None:
437
+ ap = argparse.ArgumentParser()
438
+ ap.add_argument("--gen-model", default=DEFAULT_GEN_MODEL)
439
+ ap.add_argument("--n-per-category", type=int, default=60,
440
+ help="Docs to generate per synthetic category "
441
+ "(coding_agent_harness, agile_pm, general).")
442
+ ap.add_argument("--limit", type=int, default=0,
443
+ help="If set, overrides --n-per-category to a small "
444
+ "number for a cheap smoke test.")
445
+ ap.add_argument("--only-categories", nargs="+", default=[],
446
+ help="Restrict generation to these categories (e.g. "
447
+ "--only-categories project_status), instead of "
448
+ "regenerating the whole corpus. Also skips the "
449
+ "paper doc when set.")
450
+ ap.add_argument("--skip-paper", action="store_true")
451
+ ap.add_argument("--seed", type=int, default=3407)
452
+ args = ap.parse_args()
453
+
454
+ ensure_dirs()
455
+
456
+ api_key = os.environ.get("OPENROUTER_API_KEY")
457
+ if not api_key:
458
+ raise SystemExit("OPENROUTER_API_KEY not set (expected in .env)")
459
+
460
+ client = CachedClient(
461
+ OpenAI(base_url=OPENROUTER_BASE_URL, api_key=api_key),
462
+ cache_dir=CACHE_DIR,
463
+ )
464
+ rng = random.Random(args.seed)
465
+
466
+ n_per_cat = args.limit if args.limit else args.n_per_category
467
+
468
+ docs_path = DOCS_DIR / "documents.jsonl"
469
+ qna_path = QNA_DIR / "qna.jsonl"
470
+ docs_f = docs_path.open("a")
471
+ qna_f = qna_path.open("a")
472
+
473
+ doc_counter = 0
474
+ qna_counter = 0
475
+
476
+ def emit_doc(doc_id: str, category: str, topic: str,
477
+ sections: List[Dict[str, str]], split: str) -> None:
478
+ nonlocal doc_counter, qna_counter
479
+ docs_f.write(json.dumps({
480
+ "doc_id": doc_id, "doc_version": "v1", "category": category,
481
+ "topic": topic, "split": split, "sections": sections,
482
+ }) + "\n")
483
+ doc_counter += 1
484
+
485
+ full_text = "\n\n".join(s["text"] for s in sections)
486
+ qnas = gen_qna(client, args.gen_model, full_text)
487
+ n_qna = len(qnas)
488
+ for i, qa in enumerate(qnas):
489
+ qna_split = "train" if rng.random() < 0.8 else "held_out"
490
+ qna_f.write(json.dumps({
491
+ "doc_id": doc_id, "doc_version": "v1", "split": split,
492
+ "qna_split": qna_split,
493
+ "question": qa["question"],
494
+ "prefix": f"Q: {qa['question']}\nA:",
495
+ "target": " " + qa["answer"],
496
+ }) + "\n")
497
+ qna_counter += 1
498
+ print(f" [{category}] {doc_id} ({topic[:50]}...) -> {n_qna} QAs, split={split}",
499
+ flush=True)
500
+
501
+ # 1. The real Code2LoRA paper -- always included, always in train split
502
+ # (we WANT it memorized, not held out for cross-corpus generalization
503
+ # testing -- that's the whole point of this build).
504
+ if not args.skip_paper and not args.only_categories:
505
+ print("=== paper (real, hand-authored sections) ===", flush=True)
506
+ emit_doc("code2lora_paper", "paper", "Code2LoRA paper",
507
+ code2lora_paper_sections(), split="train")
508
+
509
+ # 2. Synthetic categories
510
+ topic_lists = {
511
+ "coding_agent_harness": CODING_AGENT_TOPICS,
512
+ "agile_pm": AGILE_PM_TOPICS,
513
+ "project_status": PROJECT_STATUS_TOPICS,
514
+ "general": GENERAL_TOPICS,
515
+ }
516
+ if args.only_categories:
517
+ topic_lists = {k: v for k, v in topic_lists.items() if k in args.only_categories}
518
+ for category, topics in topic_lists.items():
519
+ print(f"=== {category} ({n_per_cat} docs) ===", flush=True)
520
+ for i in range(n_per_cat):
521
+ topic = topics[i % len(topics)]
522
+ if i >= len(topics):
523
+ topic = f"{topic} (variant {i // len(topics) + 1}, different specifics)"
524
+ doc_id = f"{category}_{i:04d}"
525
+ split = assign_cross_corpus_split(rng)
526
+ try:
527
+ if category == "project_status":
528
+ text = gen_project_status_document(client, args.gen_model, topic)
529
+ else:
530
+ text = gen_document(client, args.gen_model, category, topic)
531
+ except RuntimeError as e:
532
+ print(f" [error] skipping {doc_id}: {e}", flush=True)
533
+ continue
534
+ sections = [{"name": "body", "text": text}]
535
+ emit_doc(doc_id, category, topic, sections, split)
536
+
537
+ docs_f.close()
538
+ qna_f.close()
539
+ print(f"\nDone. {doc_counter} documents, {qna_counter} QA pairs written to:")
540
+ print(f" {docs_path}")
541
+ print(f" {qna_path}")
542
+
543
+
544
+ if __name__ == "__main__":
545
+ main()
scripts/generate_techlead_qa.py ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Generate high-quality, judgment-shaped "Tech Lead" QA from REAL GitHub
3
+ data (SWE-bench: real issues + fix patches + test patches + PR discussion),
4
+ via OpenRouter google/gemini-3.6-flash.
5
+
6
+ Design decisions baked in from this session's analysis:
7
+ - Targets are TIER-A/B *judgment* QA only (why / architecture / data-flow /
8
+ contracts / conventions / impact-NARRATIVE), never Tier-C exact-recall
9
+ ("list the precise files+lines") which a LoRA can only hallucinate.
10
+ - Answers are SHORT (a phrase/sentence) so they're compressible into a
11
+ weight-delta and gradeable.
12
+ - Each example is keyed to doc_id = "{repo}@{base_commit[:10]}" so it can
13
+ later be tied to a repo-state embedding for hypernetwork training.
14
+ - gemini-3.6-flash is a REASONING model: reasoning is mandatory and cannot
15
+ be disabled, and it consumes completion tokens BEFORE content -- so
16
+ max_tokens must be generous (default 3500) or content comes back empty.
17
+
18
+ Usage:
19
+ python scripts/generate_techlead_qa.py --limit 3 # smoke test
20
+ python scripts/generate_techlead_qa.py --max-instances 1200
21
+ """
22
+ from __future__ import annotations
23
+ import argparse, hashlib, json, os, re, sys, time
24
+ from pathlib import Path
25
+ from typing import Dict, List
26
+ from openai import OpenAI
27
+
28
+ HERE = Path(__file__).resolve().parent; REPO_ROOT = HERE.parent
29
+ sys.path.insert(0, str(REPO_ROOT))
30
+ from memory_lora.data_paths import QNA_DIR, DOCS_DIR, CACHE_DIR, ensure_dirs # noqa: E402
31
+
32
+ def _load_dotenv(p: Path):
33
+ if p.exists():
34
+ for line in p.read_text().splitlines():
35
+ if "=" in line and not line.strip().startswith("#"):
36
+ k, v = line.split("=", 1); os.environ.setdefault(k.strip(), v.strip())
37
+ _load_dotenv(REPO_ROOT / ".env")
38
+
39
+ MODEL = "google/gemini-3.6-flash"
40
+ BASE_URL = "https://openrouter.ai/api/v1"
41
+
42
+ SYSTEM = (
43
+ "You are a staff engineer writing onboarding Q&A about a real code change. "
44
+ "Given an issue, its fix patch, the test patch, and any discussion, produce "
45
+ "a JSON array of 5-8 objects with keys 'aspect', 'question', 'answer'. "
46
+ "aspect must be one of: architecture, data_flow, why, contracts, conventions, "
47
+ "impact. Rules: (1) Questions test JUDGMENT and UNDERSTANDING, not memorized "
48
+ "trivia. (2) Answers are SHORT -- one phrase or one sentence, copyable, no "
49
+ "lists of file paths or line numbers. (3) 'why' questions explain the "
50
+ "rationale/trade-off. 'impact' questions describe the KIND of thing affected "
51
+ "(a behavior, a contract), NOT an exact file enumeration. (4) Ground every "
52
+ "answer in the provided change; do not invent APIs. Output ONLY the JSON array."
53
+ )
54
+
55
+ def cache_key(*parts) -> str:
56
+ return hashlib.sha256("||".join(parts).encode()).hexdigest()[:24]
57
+
58
+ def gen_qa(client, ctx: str, cache_dir: Path, retries=4) -> List[Dict]:
59
+ key = cache_key(MODEL, ctx)
60
+ cf = cache_dir / f"tlqa_{key}.json"
61
+ if cf.exists():
62
+ raw = cf.read_text()
63
+ else:
64
+ last = None
65
+ for a in range(retries):
66
+ try:
67
+ r = client.chat.completions.create(
68
+ model=MODEL,
69
+ messages=[{"role": "system", "content": SYSTEM},
70
+ {"role": "user", "content": ctx}],
71
+ max_tokens=3500, temperature=0.6)
72
+ raw = r.choices[0].message.content or ""
73
+ cf.write_text(raw); break
74
+ except Exception as e: # noqa: BLE001
75
+ last = e; time.sleep(2 ** a)
76
+ else:
77
+ print(f" [warn] failed: {last}", flush=True); return []
78
+ m = re.search(r"\[.*\]", raw, re.DOTALL)
79
+ if not m: return []
80
+ try:
81
+ items = json.loads(m.group(0))
82
+ except json.JSONDecodeError:
83
+ return []
84
+ out = []
85
+ for it in items:
86
+ q = (it.get("question") or "").strip()
87
+ a = (it.get("answer") or "").strip()
88
+ asp = (it.get("aspect") or "general").strip()
89
+ if q and a and len(a) < 240:
90
+ out.append({"aspect": asp, "question": q, "answer": a})
91
+ return out
92
+
93
+ def build_ctx(row) -> str:
94
+ def clip(s, n): return (s or "")[:n]
95
+ return (f"REPO: {row['repo']}\n"
96
+ f"ISSUE:\n{clip(row.get('problem_statement'),1500)}\n\n"
97
+ f"DISCUSSION:\n{clip(row.get('hints_text'),800)}\n\n"
98
+ f"FIX PATCH:\n{clip(row.get('patch'),2500)}\n\n"
99
+ f"TEST PATCH:\n{clip(row.get('test_patch'),1200)}")
100
+
101
+ def main():
102
+ ap = argparse.ArgumentParser()
103
+ ap.add_argument("--max-instances", type=int, default=1200)
104
+ ap.add_argument("--limit", type=int, default=0, help="smoke-test cap")
105
+ ap.add_argument("--split", default="test")
106
+ args = ap.parse_args()
107
+ ensure_dirs()
108
+ api_key = os.environ.get("OPENROUTER_API_KEY")
109
+ if not api_key: raise SystemExit("OPENROUTER_API_KEY not set")
110
+ client = OpenAI(base_url=BASE_URL, api_key=api_key)
111
+
112
+ from datasets import load_dataset
113
+ ds = load_dataset("princeton-nlp/SWE-bench", split=args.split, streaming=True)
114
+
115
+ n_max = args.limit if args.limit else args.max_instances
116
+ qna_f = (QNA_DIR / "techlead_qa.jsonl").open("a")
117
+ src_f = (DOCS_DIR / "techlead_sources.jsonl").open("a")
118
+ n_docs = n_qa = 0
119
+ t0 = time.time()
120
+ for row in ds:
121
+ if n_docs >= n_max: break
122
+ doc_id = f"{row['repo']}@{row['base_commit'][:10]}"
123
+ ctx = build_ctx(row)
124
+ qas = gen_qa(client, ctx, CACHE_DIR)
125
+ if not qas: continue
126
+ # store the source context so a repo-state embedding can be built later
127
+ src_f.write(json.dumps({"doc_id": doc_id, "repo": row["repo"],
128
+ "base_commit": row["base_commit"], "context": ctx}) + "\n")
129
+ for qa in qas:
130
+ qna_f.write(json.dumps({
131
+ "doc_id": doc_id, "doc_version": row["base_commit"],
132
+ "split": "train", "qna_split": "train",
133
+ "aspect": qa["aspect"], "question": qa["question"],
134
+ "prefix": f"Q: {qa['question']}\nA:", "target": " " + qa["answer"],
135
+ }) + "\n")
136
+ n_qa += 1
137
+ n_docs += 1
138
+ if n_docs % 10 == 0:
139
+ rate = n_docs / max(1e-9, (time.time() - t0) / 60)
140
+ print(f" {n_docs} instances, {n_qa} QA ({rate:.1f} inst/min) latest={doc_id}", flush=True)
141
+ qna_f.close(); src_f.close()
142
+ print(f"\nDone. {n_docs} real instances -> {n_qa} judgment-QA pairs.", flush=True)
143
+ print(f" {QNA_DIR/'techlead_qa.jsonl'}\n {DOCS_DIR/'techlead_sources.jsonl'}", flush=True)
144
+
145
+ if __name__ == "__main__":
146
+ main()
scripts/merge_corpora.py ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Merge the real Code2LoRA/RepoPeftBench corpus (73,849 real repo-commit
3
+ docs, 443,798 real assertion-completion QnAs) with our synthetic corpus
4
+ (211 docs: the Code2LoRA paper + coding-agent-harness + agile/Jira +
5
+ general fact-sheets) into one combined training set for the hypernetwork.
6
+
7
+ Output:
8
+ data/embeddings/combined_embeddings.parquet
9
+ data/qna/combined_qna.jsonl
10
+
11
+ Usage:
12
+ python scripts/merge_corpora.py
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ import json
18
+ import sys
19
+ from pathlib import Path
20
+
21
+ import pyarrow as pa
22
+ import pyarrow.parquet as pq
23
+
24
+ HERE = Path(__file__).resolve().parent
25
+ REPO_ROOT = HERE.parent
26
+ sys.path.insert(0, str(REPO_ROOT))
27
+ from memory_lora.data_paths import EMBEDDINGS_DIR, QNA_DIR, ensure_dirs # noqa: E402
28
+
29
+
30
+ def merge_embeddings() -> int:
31
+ synthetic_path = EMBEDDINGS_DIR / "doc_embeddings.parquet"
32
+ real_path = EMBEDDINGS_DIR / "real_code2lora_embeddings.parquet"
33
+ out_path = EMBEDDINGS_DIR / "combined_embeddings.parquet"
34
+
35
+ tables = []
36
+ for p, label in [(synthetic_path, "synthetic"), (real_path, "real")]:
37
+ if not p.exists():
38
+ print(f" [skip] {p} not found", flush=True)
39
+ continue
40
+ t = pq.read_table(p)
41
+ print(f" {label}: {t.num_rows} rows, columns={t.column_names}", flush=True)
42
+ tables.append(t.select(["doc_id", "doc_version", "split", "category", "doc_embedding"]))
43
+
44
+ combined = pa.concat_tables(tables)
45
+ pq.write_table(combined, out_path)
46
+ print(f"Wrote {combined.num_rows} combined embeddings -> {out_path}", flush=True)
47
+ return combined.num_rows
48
+
49
+
50
+ def merge_qna() -> int:
51
+ synthetic_path = QNA_DIR / "qna.jsonl"
52
+ real_path = QNA_DIR / "real_code2lora_qna.jsonl"
53
+ out_path = QNA_DIR / "combined_qna.jsonl"
54
+
55
+ n = 0
56
+ with out_path.open("w") as out:
57
+ for p, label in [(synthetic_path, "synthetic"), (real_path, "real")]:
58
+ if not p.exists():
59
+ print(f" [skip] {p} not found", flush=True)
60
+ continue
61
+ count = 0
62
+ with p.open() as f:
63
+ for line in f:
64
+ line = line.strip()
65
+ if not line:
66
+ continue
67
+ out.write(line + "\n")
68
+ count += 1
69
+ n += 1
70
+ print(f" {label}: {count} QnA rows", flush=True)
71
+ print(f"Wrote {n} combined QnA pairs -> {out_path}", flush=True)
72
+ return n
73
+
74
+
75
+ def main() -> None:
76
+ ensure_dirs()
77
+ print("Merging embeddings...", flush=True)
78
+ n_docs = merge_embeddings()
79
+ print("\nMerging QnA...", flush=True)
80
+ n_qna = merge_qna()
81
+ print(f"\nCombined corpus: {n_docs} documents, {n_qna} QnA pairs.", flush=True)
82
+
83
+
84
+ if __name__ == "__main__":
85
+ main()
scripts/show_eval_examples.py ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Show concrete held-out examples: for a few cr_test docs (both REAL repos
3
+ and synthetic), inject the hypernetwork-generated adapter and print
4
+ question -> gold vs base-model vs adapted-model prediction, so we can SEE
5
+ what the eval actually measured. CPU-only."""
6
+ from __future__ import annotations
7
+ import json, random, sys
8
+ from pathlib import Path
9
+ import numpy as np, torch
10
+ HERE = Path(__file__).resolve().parent; REPO_ROOT = HERE.parent
11
+ sys.path.insert(0, str(REPO_ROOT))
12
+ from memory_lora.core import (MemoryLoRAHead, get_module_specs, replace_with_lora,
13
+ inject_lora_weights, load_doc_rows, load_qna_rows, DEFAULT_ROOT_PREFIX)
14
+ from transformers import AutoModelForImageTextToText, AutoTokenizer
15
+ TM = ["q_proj","k_proj","v_proj","o_proj","up_proj","gate_proj","down_proj"]
16
+
17
+ @torch.no_grad()
18
+ def gen(model, tok, prefix, n=12):
19
+ enc = tok(prefix, return_tensors="pt")
20
+ out = model.generate(**enc, max_new_tokens=n, do_sample=False,
21
+ pad_token_id=tok.pad_token_id or tok.eos_token_id)
22
+ return tok.decode(out[0][enc["input_ids"].shape[1]:], skip_special_tokens=True).split("\n")[0]
23
+
24
+ def main():
25
+ ckpt = torch.load("runs/full_real_v4/head.best.pt", map_location="cpu")
26
+ tok = AutoTokenizer.from_pretrained("google/gemma-4-E2B")
27
+ if tok.pad_token is None: tok.pad_token = tok.eos_token
28
+ print("loading base model on CPU...", flush=True)
29
+ model = AutoModelForImageTextToText.from_pretrained("google/gemma-4-E2B",
30
+ torch_dtype=torch.float32, attn_implementation="eager", low_cpu_mem_usage=True)
31
+ model.eval()
32
+ for p in model.parameters(): p.requires_grad = False
33
+ specs = get_module_specs(model, TM, root_prefix=DEFAULT_ROOT_PREFIX)
34
+ replace_with_lora(model, specs, rank=ckpt["config"]["rank"], alpha=ckpt["args"].get("alpha",32.0))
35
+ head = MemoryLoRAHead(input_dim=ckpt["config"]["input_dim"],
36
+ type_dims={k:tuple(v) for k,v in ckpt["config"]["type_dims"].items()},
37
+ hidden_dim=ckpt["config"]["hidden_dim"], rank=ckpt["config"]["rank"])
38
+ head.load_state_dict(ckpt["state_dict"]); head.eval()
39
+
40
+ docs = load_doc_rows("data/embeddings/combined_embeddings.parquet")
41
+ qnas = load_qna_rows("data/qna/combined_qna.jsonl")
42
+ by_doc = {}
43
+ for q in qnas:
44
+ if q.split == "cr_test": by_doc.setdefault(q.doc_id, []).append(q)
45
+ doc_by_id = {d.doc_id: d for d in docs}
46
+
47
+ real = [d for d in by_doc if "@" in d and d in doc_by_id] # real repos
48
+ synth = [d for d in by_doc if "@" not in d and d in doc_by_id] # synthetic
49
+ rng = random.Random(1)
50
+ picks = rng.sample(real, min(4,len(real))) + rng.sample(synth, min(2,len(synth)))
51
+ named = dict(model.named_modules())
52
+
53
+ for doc_id in picks:
54
+ d = doc_by_id[doc_id]
55
+ kind = "REAL REPO" if "@" in doc_id else "SYNTHETIC"
56
+ ctx = torch.from_numpy(d.doc_embedding).unsqueeze(0)
57
+ head_out = head(ctx)
58
+ pairs = by_doc[doc_id][:2]
59
+ print(f"\n========== [{kind}] {doc_id} ==========", flush=True)
60
+ for q in pairs:
61
+ for sp in specs: named[sp.full_name].A=None; named[sp.full_name].B=None
62
+ base = gen(model, tok, q.prefix)
63
+ inject_lora_weights(model, specs, head_out, batch_index=0)
64
+ adapt = gen(model, tok, q.prefix)
65
+ ok = adapt.strip().rstrip('.').lower().startswith(q.target.strip().rstrip('.').lower()) or \
66
+ q.target.strip().lower().startswith(adapt.strip().lower())
67
+ print(f" Q: {q.prefix.strip()[:90].replace(chr(10),' ')}", flush=True)
68
+ print(f" gold={q.target.strip()!r} base={base.strip()!r} adapted={adapt.strip()!r} {'OK' if ok else 'X'}", flush=True)
69
+
70
+ if __name__ == "__main__":
71
+ main()
scripts/test_embed_this_repo.py ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Step A of the side recall-test: embed THIS repo (gemma4-hack) with the
3
+ frozen encoder in a short-lived, low-memory process, save the 2048-d vector
4
+ to disk, and exit -- so the big base-model process (Step B) never has the
5
+ encoder resident at the same time. CPU-only to avoid competing with the
6
+ live MPS training run."""
7
+ from __future__ import annotations
8
+ import sys, gc
9
+ from pathlib import Path
10
+ import numpy as np
11
+ HERE = Path(__file__).resolve().parent; REPO_ROOT = HERE.parent
12
+ sys.path.insert(0, str(REPO_ROOT))
13
+ from memory_lora.encoder import load_encoder, embed_document
14
+ from memory_lora.codegraph import extract_repo_graph_sections, extract_repo_dependency_summary
15
+
16
+ def main():
17
+ skip = {".git","venv","__pycache__","data","runs",".mypy_cache","scratchpad"}
18
+ print("Extracting codegraph sections from this repo...", flush=True)
19
+ graph_sections = extract_repo_graph_sections(REPO_ROOT, max_files=60, skip_dirs=skip)
20
+ dep = extract_repo_dependency_summary(REPO_ROOT, skip_dirs=skip)
21
+ sections = list(graph_sections)
22
+ if dep:
23
+ sections.append(("dependency_graph", dep))
24
+ # also add a few raw key files for content signal
25
+ for rel in ["memory_lora/core.py", "memory_lora/encoder.py", "scripts/train_memory_lora.py",
26
+ "memory_lora/codegraph.py", "requirements.txt"]:
27
+ p = REPO_ROOT / rel
28
+ if p.exists():
29
+ sections.append((f"raw:{rel}", p.read_text(errors="ignore")))
30
+ print(f" {len(sections)} sections", flush=True)
31
+
32
+ print("Loading encoder on CPU...", flush=True)
33
+ model, tok = load_encoder(device="cpu")
34
+ vec = embed_document(sections, model, tok, "cpu", chunk_tokens=2048, chunk_overlap=256, batch_size=2)
35
+ del model, tok; gc.collect()
36
+ if vec is None:
37
+ print("FAILED: no embedding", flush=True); return
38
+ out = REPO_ROOT / "runs" / "this_repo_emb.npy"
39
+ np.save(out, vec.numpy().astype("float32"))
40
+ print(f"Saved repo embedding {tuple(vec.shape)} -> {out}", flush=True)
41
+
42
+ if __name__ == "__main__":
43
+ main()
scripts/test_recall_this_repo.py ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Step B of the side recall-test. Loads base Gemma-4-E2B on CPU, generates
3
+ a LoRA for THIS repo from its precomputed embedding (Step A) via the
4
+ currently-training hypernetwork's latest checkpoint, and compares base vs
5
+ adapted completions on prompts drawn from this repo's own code.
6
+
7
+ CPU-only (never touches the live MPS training). Peak memory ~= just the
8
+ base model (~10GB) since the encoder already ran and exited in Step A.
9
+
10
+ Note on interpretation: the hypernetwork was trained on pytest
11
+ ASSERTION-COMPLETION over real repos, and THIS repo is unseen (true
12
+ cross-repo test). Prompts are shaped to probe whether the generated
13
+ adapter biases the frozen model toward this repo's specific identifiers/
14
+ values vs the base model's generic guess.
15
+ """
16
+ from __future__ import annotations
17
+ import sys
18
+ from pathlib import Path
19
+ import numpy as np, torch
20
+ HERE = Path(__file__).resolve().parent; REPO_ROOT = HERE.parent
21
+ sys.path.insert(0, str(REPO_ROOT))
22
+ from memory_lora.core import (MemoryLoRAHead, get_module_specs, replace_with_lora,
23
+ inject_lora_weights, DEFAULT_ROOT_PREFIX)
24
+ from transformers import AutoModelForImageTextToText, AutoTokenizer
25
+
26
+ TARGET_MODULES = ["q_proj","k_proj","v_proj","o_proj","up_proj","gate_proj","down_proj"]
27
+
28
+ # Prompts drawn from THIS repo's actual code / conventions. Each is cut right
29
+ # before a repo-specific value the adapter should help recall.
30
+ PROMPTS = [
31
+ ("from memory_lora.core import MemoryLoRAHead\n"
32
+ "def test_default_rank():\n"
33
+ " head = MemoryLoRAHead(input_dim=2048, type_dims={})\n"
34
+ " assert head.rank ==", "16"),
35
+ ("# memory_lora/core.py sets the LoRA injection root for Gemma-4-E2B\n"
36
+ "DEFAULT_ROOT_PREFIX =", '"model.language_model."'),
37
+ ("# memory_lora/encoder.py default frozen embedding model\n"
38
+ "DEFAULT_EMBED_MODEL =", '"Qwen/Qwen3-Embedding-0.6B"'),
39
+ ("# scripts/train_memory_lora.py base model being adapted\n"
40
+ "DEFAULT_MODEL =", '"google/gemma-4-E2B"'),
41
+ ("from memory_lora.core import MemoryLoRAHead\n"
42
+ "def test_hidden_dim():\n"
43
+ " h = MemoryLoRAHead(input_dim=2048, type_dims={})\n"
44
+ " assert h.hidden_dim ==", "128"),
45
+ ("# the seven attention/MLP projection types Memory-LoRA targets\n"
46
+ "DEFAULT_TARGET_MODULES = [\"q_proj\", \"k_proj\", \"v_proj\", \"o_proj\",", '"up_proj"'),
47
+ ]
48
+
49
+
50
+ @torch.no_grad()
51
+ def gen(model, tok, prefix, max_new=14):
52
+ enc = tok(prefix, return_tensors="pt")
53
+ out = model.generate(**enc, max_new_tokens=max_new, do_sample=False,
54
+ pad_token_id=tok.pad_token_id or tok.eos_token_id)
55
+ return tok.decode(out[0][enc["input_ids"].shape[1]:], skip_special_tokens=True).split("\n")[0]
56
+
57
+
58
+ def main():
59
+ print("Loading base google/gemma-4-E2B on CPU (bounded ~10GB)...", flush=True)
60
+ tok = AutoTokenizer.from_pretrained("google/gemma-4-E2B")
61
+ if tok.pad_token is None: tok.pad_token = tok.eos_token
62
+ model = AutoModelForImageTextToText.from_pretrained(
63
+ "google/gemma-4-E2B", torch_dtype=torch.float32, low_cpu_mem_usage=True)
64
+ model.eval()
65
+ for p in model.parameters(): p.requires_grad = False
66
+ print(" loaded.", flush=True)
67
+
68
+ ckpt = torch.load(REPO_ROOT / "runs" / "test_ckpt.pt", map_location="cpu")
69
+ specs = get_module_specs(model, TARGET_MODULES, root_prefix=DEFAULT_ROOT_PREFIX)
70
+ replace_with_lora(model, specs, rank=ckpt["config"]["rank"], alpha=ckpt["args"].get("alpha", 32.0))
71
+ head = MemoryLoRAHead(input_dim=ckpt["config"]["input_dim"],
72
+ type_dims={k: tuple(v) for k, v in ckpt["config"]["type_dims"].items()},
73
+ hidden_dim=ckpt["config"]["hidden_dim"], rank=ckpt["config"]["rank"])
74
+ head.load_state_dict(ckpt["state_dict"]); head.eval()
75
+
76
+ repo_emb = torch.from_numpy(np.load(REPO_ROOT / "runs" / "this_repo_emb.npy")).unsqueeze(0)
77
+ head_out = head(repo_emb)
78
+ print(f" generated adapter for THIS repo (unseen). "
79
+ f"training step in checkpoint: {ckpt['args'].get('epochs','?')} epochs cfg\n", flush=True)
80
+
81
+ named = dict(model.named_modules())
82
+ for prefix, gold in PROMPTS:
83
+ # base: no adapter
84
+ for sp in specs:
85
+ named[sp.full_name].A = None; named[sp.full_name].B = None
86
+ base = gen(model, tok, prefix)
87
+ # adapted: inject this repo's generated LoRA
88
+ inject_lora_weights(model, specs, head_out, batch_index=0)
89
+ adapted = gen(model, tok, prefix)
90
+ tag = prefix.strip().split("\n")[-1][:55]
91
+ print(f"PROMPT: ...{tag}", flush=True)
92
+ print(f" gold: {gold}", flush=True)
93
+ print(f" base: {base!r}", flush=True)
94
+ print(f" adapted: {adapted!r}", flush=True)
95
+ print(flush=True)
96
+
97
+
98
+ if __name__ == "__main__":
99
+ main()
scripts/train_direct_lora.py ADDED
@@ -0,0 +1,277 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Train a standalone, directly-parameterized LoRA adapter on priority
3
+ document(s) -- NOT hypernetwork-generated.
4
+
5
+ Why this exists (see runs/full1, runs/full2, runs/full3_priority logs):
6
+ a single hypernetwork trunk shared across 165+ documents cannot
7
+ simultaneously (a) generalize broadly across the corpus and (b) reliably
8
+ memorize any one document's specific facts -- three separate interventions
9
+ (bigger head, oversampling) each improved (b) only by making (a) collapse
10
+ faster, because they all perturb the SAME shared trunk weights.
11
+
12
+ This script sidesteps the tension entirely for content we don't need
13
+ zero-shot generalization on (documents we already have and specifically
14
+ want memorized, e.g. the Code2LoRA paper): instead of a hypernetwork
15
+ mapping embedding->weights, the LoRA A/B matrices are ordinary
16
+ ``nn.Parameter`` tensors trained directly via backprop on exactly the
17
+ QA pairs for the selected doc_id(s) -- standard PEFT-style fine-tuning,
18
+ with the same LoRA wrapper class (``memory_lora.core.LoRA``) and the same
19
+ frozen Gemma-4-E2B target modules as the hypernetwork path, so results are
20
+ directly comparable and the diagnostic single-doc runs (which proved this
21
+ converges to correct multi-fact recall) apply unchanged.
22
+
23
+ Usage:
24
+ python scripts/train_direct_lora.py --output-dir direct_paper \\
25
+ --doc-ids code2lora_paper --epochs 300
26
+ """
27
+
28
+ from __future__ import annotations
29
+
30
+ import argparse
31
+ import json
32
+ import random
33
+ import sys
34
+ import time
35
+ from pathlib import Path
36
+ from typing import Any, Dict, List
37
+
38
+ import numpy as np
39
+ import torch
40
+ import torch.nn as nn
41
+ import torch.nn.functional as F
42
+ from transformers import AutoModelForImageTextToText, AutoTokenizer, get_cosine_schedule_with_warmup
43
+
44
+ HERE = Path(__file__).resolve().parent
45
+ REPO_ROOT = HERE.parent
46
+ sys.path.insert(0, str(REPO_ROOT))
47
+ from memory_lora.data_paths import QNA_DIR, RUNS_DIR, ensure_dirs # noqa: E402
48
+ from memory_lora.core import ( # noqa: E402
49
+ DEFAULT_ROOT_PREFIX,
50
+ discover_module_types_and_dims,
51
+ get_module_specs,
52
+ load_qna_rows,
53
+ replace_with_lora,
54
+ )
55
+
56
+ DEFAULT_MODEL = "google/gemma-4-E2B"
57
+ DEFAULT_TARGET_MODULES = [
58
+ "q_proj", "k_proj", "v_proj", "o_proj",
59
+ "up_proj", "gate_proj", "down_proj",
60
+ ]
61
+
62
+
63
+ def _tokenize_lm_batch(tokenizer, prefixes: List[str], targets: List[str],
64
+ max_seq_len: int = 384) -> Dict[str, torch.Tensor]:
65
+ eos = tokenizer.eos_token or ""
66
+ input_ids_list, labels_list = [], []
67
+ for p, t in zip(prefixes, targets):
68
+ t_ids = tokenizer(t + eos, add_special_tokens=False)["input_ids"]
69
+ if not t_ids:
70
+ continue
71
+ prefix_budget = max(8, max_seq_len - len(t_ids))
72
+ p_ids_full = tokenizer(p, add_special_tokens=False)["input_ids"]
73
+ p_ids = p_ids_full[-prefix_budget:] if len(p_ids_full) > prefix_budget else p_ids_full
74
+ ids = p_ids + t_ids
75
+ labels = ([-100] * len(p_ids)) + list(t_ids)
76
+ input_ids_list.append(torch.tensor(ids, dtype=torch.long))
77
+ labels_list.append(torch.tensor(labels, dtype=torch.long))
78
+ if not input_ids_list:
79
+ return {}
80
+ L = max(t.size(0) for t in input_ids_list)
81
+ pad_id = tokenizer.pad_token_id or 0
82
+
83
+ def _lpad(x, val):
84
+ return F.pad(x, (L - x.size(0), 0), value=val)
85
+
86
+ input_ids = torch.stack([_lpad(t, pad_id) for t in input_ids_list], 0)
87
+ labels = torch.stack([_lpad(t, -100) for t in labels_list], 0)
88
+ attn_list = [torch.ones(t.size(0), dtype=torch.long) for t in input_ids_list]
89
+ attn = torch.stack([_lpad(t, 0) for t in attn_list], 0)
90
+ return {"input_ids": input_ids, "labels": labels, "attention_mask": attn}
91
+
92
+
93
+ def init_direct_lora_params(model: nn.Module, specs, rank: int, device, dtype) -> Dict[str, Dict[str, nn.Parameter]]:
94
+ """Give each LoRA wrapper its OWN trainable (A, B), instead of an
95
+ externally-injected tensor from a hypernetwork. B initialized to zero
96
+ (standard LoRA init) so the adapter starts as a no-op."""
97
+ named = dict(model.named_modules())
98
+ params: Dict[str, Dict[str, nn.Parameter]] = {}
99
+ for sp in specs:
100
+ lora_mod = named[sp.full_name]
101
+ A = nn.Parameter(torch.randn(rank, sp.in_features, device=device, dtype=torch.float32) * 0.01)
102
+ B = nn.Parameter(torch.zeros(sp.out_features, rank, device=device, dtype=torch.float32))
103
+ lora_mod.set_lora_weights(A, B)
104
+ params[sp.full_name] = {"A": A, "B": B}
105
+ return params
106
+
107
+
108
+ def main() -> None:
109
+ ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
110
+ ap.add_argument("--qna-path", default=str(QNA_DIR / "qna.jsonl"))
111
+ ap.add_argument("--output-dir", required=True)
112
+ ap.add_argument("--model-name", default=DEFAULT_MODEL)
113
+ ap.add_argument("--target-modules", nargs="+", default=DEFAULT_TARGET_MODULES)
114
+ ap.add_argument("--root-prefix", default=DEFAULT_ROOT_PREFIX)
115
+ ap.add_argument("--doc-ids", nargs="+", default=[],
116
+ help="Train a single direct LoRA jointly on the union "
117
+ "of these documents' QnAs (use one doc_id for a "
118
+ "dedicated per-document adapter).")
119
+ ap.add_argument("--doc-ids-file", default="",
120
+ help="Alternative to --doc-ids: path to a file with "
121
+ "whitespace-separated doc_ids. Avoids shell "
122
+ "word-splitting pitfalls (e.g. zsh does not "
123
+ "word-split unquoted $VAR by default) for large "
124
+ "doc-id lists.")
125
+ ap.add_argument("--rank", type=int, default=32)
126
+ ap.add_argument("--alpha", type=float, default=64.0)
127
+ ap.add_argument("--epochs", type=int, default=300)
128
+ ap.add_argument("--lr", type=float, default=3e-4)
129
+ ap.add_argument("--weight-decay", type=float, default=0.0)
130
+ ap.add_argument("--warmup-ratio", type=float, default=0.05)
131
+ ap.add_argument("--max-grad-norm", type=float, default=1.0)
132
+ ap.add_argument("--max-seq-len", type=int, default=384)
133
+ ap.add_argument("--lm-micro-batch", type=int, default=4)
134
+ ap.add_argument("--eval-every-epochs", type=int, default=10)
135
+ ap.add_argument("--epoch-ckpt-every", type=int, default=25)
136
+ ap.add_argument("--seed", type=int, default=3407)
137
+ ap.add_argument("--device", default="mps")
138
+ ap.add_argument("--dtype", default="bfloat16", choices=["bfloat16", "float16", "float32"])
139
+ ap.add_argument("--attn-implementation", default="sdpa", choices=["sdpa", "eager"])
140
+ ap.add_argument("--gradient-checkpointing", action="store_true", default=True)
141
+ ap.add_argument("--no-gradient-checkpointing", dest="gradient_checkpointing", action="store_false")
142
+ args = ap.parse_args()
143
+
144
+ out_dir = Path(args.output_dir)
145
+ if not out_dir.is_absolute():
146
+ out_dir = RUNS_DIR / out_dir
147
+ out_dir.mkdir(parents=True, exist_ok=True)
148
+ ensure_dirs()
149
+
150
+ device = torch.device(args.device if (args.device != "mps" or torch.backends.mps.is_available()) else "cpu")
151
+ dtype = {"bfloat16": torch.bfloat16, "float16": torch.float16, "float32": torch.float32}[args.dtype]
152
+ random.seed(args.seed)
153
+ np.random.seed(args.seed)
154
+ torch.manual_seed(args.seed)
155
+
156
+ if args.doc_ids_file:
157
+ file_ids = Path(args.doc_ids_file).read_text().split()
158
+ doc_ids = set(args.doc_ids) | set(file_ids)
159
+ else:
160
+ doc_ids = set(args.doc_ids)
161
+ if not doc_ids:
162
+ raise SystemExit("No --doc-ids or --doc-ids-file provided.")
163
+ print(f"Training a direct (non-hypernetwork) LoRA jointly on: {sorted(doc_ids)}", flush=True)
164
+ all_qnas = load_qna_rows(Path(args.qna_path))
165
+ train_qnas = [q for q in all_qnas if q.doc_id in doc_ids and q.qna_split == "train"]
166
+ held_out_qnas = [q for q in all_qnas if q.doc_id in doc_ids and q.qna_split == "held_out"]
167
+ print(f" {len(train_qnas)} train QAs, {len(held_out_qnas)} held-out QAs", flush=True)
168
+ if not train_qnas:
169
+ raise SystemExit("No train QnAs found for the given --doc-ids.")
170
+
171
+ print(f"Loading {args.model_name} ...", flush=True)
172
+ tokenizer = AutoTokenizer.from_pretrained(args.model_name)
173
+ if tokenizer.pad_token is None:
174
+ tokenizer.pad_token = tokenizer.eos_token
175
+ base_model = AutoModelForImageTextToText.from_pretrained(
176
+ args.model_name, torch_dtype=dtype, attn_implementation=args.attn_implementation,
177
+ ).to(device)
178
+ base_model.eval()
179
+ for p in base_model.parameters():
180
+ p.requires_grad = False
181
+ if args.gradient_checkpointing:
182
+ base_model.config.use_cache = False
183
+ base_model.gradient_checkpointing_enable(gradient_checkpointing_kwargs={"use_reentrant": False})
184
+ print(" gradient checkpointing: ON", flush=True)
185
+
186
+ specs = get_module_specs(base_model, args.target_modules, root_prefix=args.root_prefix)
187
+ type_dims = discover_module_types_and_dims(specs)
188
+ print(f" discovered {len(specs)} target modules, {len(type_dims)} shape-types", flush=True)
189
+ replace_with_lora(base_model, specs, rank=args.rank, alpha=args.alpha)
190
+ lora_params = init_direct_lora_params(base_model, specs, args.rank, device, dtype)
191
+ all_params = [p for pair in lora_params.values() for p in pair.values()]
192
+ n_params = sum(p.numel() for p in all_params)
193
+ print(f" direct LoRA trainable params: {n_params / 1e6:.2f}M "
194
+ f"(rank={args.rank}, {len(specs)} modules)", flush=True)
195
+
196
+ optim = torch.optim.AdamW(all_params, lr=args.lr, weight_decay=args.weight_decay)
197
+ total_steps = args.epochs
198
+ warmup_steps = max(1, int(total_steps * args.warmup_ratio))
199
+ sched = get_cosine_schedule_with_warmup(optim, warmup_steps, total_steps)
200
+
201
+ def _save(name: str) -> Path:
202
+ out = out_dir / f"lora.{name}.pt"
203
+ state = {full_name: {"A": pair["A"].detach().cpu(), "B": pair["B"].detach().cpu()}
204
+ for full_name, pair in lora_params.items()}
205
+ torch.save({"lora": state, "rank": args.rank, "alpha": args.alpha,
206
+ "doc_ids": sorted(doc_ids), "target_modules": args.target_modules,
207
+ "root_prefix": args.root_prefix}, out)
208
+ return out
209
+
210
+ @torch.no_grad()
211
+ def _eval_held_out() -> float:
212
+ if not held_out_qnas:
213
+ return float("nan")
214
+ base_model.eval()
215
+ total_loss, total_tok = 0.0, 0
216
+ prefixes = [q.prefix for q in held_out_qnas]
217
+ targets = [q.target for q in held_out_qnas]
218
+ for i in range(0, len(prefixes), args.lm_micro_batch):
219
+ j = min(i + args.lm_micro_batch, len(prefixes))
220
+ batch = _tokenize_lm_batch(tokenizer, prefixes[i:j], targets[i:j], max_seq_len=args.max_seq_len)
221
+ if not batch:
222
+ continue
223
+ batch = {k: v.to(device) for k, v in batch.items()}
224
+ out = base_model(**batch)
225
+ ntok = (batch["labels"] != -100).sum().item()
226
+ total_loss += out.loss.item() * ntok
227
+ total_tok += ntok
228
+ return total_loss / max(total_tok, 1)
229
+
230
+ prefixes_all = [q.prefix for q in train_qnas]
231
+ targets_all = [q.target for q in train_qnas]
232
+ metrics_log: List[Dict[str, Any]] = []
233
+ t0 = time.time()
234
+ for epoch in range(args.epochs):
235
+ order = list(range(len(prefixes_all)))
236
+ random.shuffle(order)
237
+ prefixes = [prefixes_all[i] for i in order]
238
+ targets = [targets_all[i] for i in order]
239
+ loss_acc, n_tok_seen = 0.0, 0
240
+ for i in range(0, len(prefixes), args.lm_micro_batch):
241
+ j = min(i + args.lm_micro_batch, len(prefixes))
242
+ batch = _tokenize_lm_batch(tokenizer, prefixes[i:j], targets[i:j], max_seq_len=args.max_seq_len)
243
+ if not batch:
244
+ continue
245
+ batch = {k: v.to(device) for k, v in batch.items()}
246
+ out = base_model(**batch)
247
+ ntok = (batch["labels"] != -100).sum().item()
248
+ loss = out.loss * ntok
249
+ loss.backward()
250
+ loss_acc += loss.detach().item()
251
+ n_tok_seen += ntok
252
+ torch.nn.utils.clip_grad_norm_(all_params, args.max_grad_norm)
253
+ optim.step()
254
+ sched.step()
255
+ optim.zero_grad(set_to_none=True)
256
+
257
+ avg = loss_acc / max(n_tok_seen, 1)
258
+ elapsed = (time.time() - t0) / 60
259
+ if epoch % 10 == 0 or epoch == args.epochs - 1:
260
+ print(f"[ep{epoch}] train_loss={avg:.4f} lr={sched.get_last_lr()[0]:.2e} elapsed={elapsed:.1f}m", flush=True)
261
+
262
+ if epoch % max(1, args.eval_every_epochs) == 0 or epoch == args.epochs - 1:
263
+ held_out_loss = _eval_held_out()
264
+ print(f" [eval] ep{epoch} held_out_loss={held_out_loss:.4f}", flush=True)
265
+ metrics_log.append({"epoch": epoch, "train_loss": avg, "held_out_loss": held_out_loss})
266
+ (out_dir / "metrics.jsonl").open("a").write(json.dumps(metrics_log[-1]) + "\n")
267
+
268
+ if epoch % max(1, args.epoch_ckpt_every) == 0 or epoch == args.epochs - 1:
269
+ p = _save(f"ep{epoch}")
270
+ print(f" [ckpt] -> {p}", flush=True)
271
+ _save("latest")
272
+
273
+ print(f"\nDirect LoRA training done. Final train_loss={avg:.4f}", flush=True)
274
+
275
+
276
+ if __name__ == "__main__":
277
+ main()
scripts/train_memory_lora.py ADDED
@@ -0,0 +1,668 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Train the Memory-LoRA hypernetwork on google/gemma-4-E2B.
3
+
4
+ Forked from Code2LoRA's ``hypernetwork/train_code2lora_static_v2.py``
5
+ (direct-projection trainer), retargeted:
6
+
7
+ * repo embedding -> doc embedding (memory_lora/encoder.py output)
8
+ * Qwen2.5-Coder -> google/gemma-4-E2B (memory_lora/core.py target modules)
9
+ * cuda + flash_attn2 -> mps + sdpa (falls back to eager)
10
+ * no wandb/TRL -> plain PyTorch loop + TensorBoard (SummaryWriter)
11
+
12
+ Same core trick as the paper: only the hypernetwork head is trained; the
13
+ base LLM is frozen (gradient-checkpointed for memory headroom); LoRA A/B
14
+ tensors are non-detached so the causal-LM loss's backward graph flows
15
+ straight into the head's parameters.
16
+
17
+ Usage:
18
+ python scripts/train_memory_lora.py --output-dir runs/pilot1 \\
19
+ --limit-train-docs 5 --epochs 1 # smoke test
20
+
21
+ python scripts/train_memory_lora.py --output-dir runs/full1
22
+ """
23
+
24
+ from __future__ import annotations
25
+
26
+ import argparse
27
+ import json
28
+ import random
29
+ import sys
30
+ import time
31
+ from pathlib import Path
32
+ from typing import Any, Dict, List, Optional, Tuple
33
+
34
+ import numpy as np
35
+ import psutil
36
+ import torch
37
+ import torch.nn as nn
38
+ import torch.nn.functional as F
39
+ from torch.utils.tensorboard import SummaryWriter
40
+ from transformers import (
41
+ AutoModelForImageTextToText,
42
+ AutoTokenizer,
43
+ get_cosine_schedule_with_warmup,
44
+ )
45
+
46
+ HERE = Path(__file__).resolve().parent
47
+ REPO_ROOT = HERE.parent
48
+ sys.path.insert(0, str(REPO_ROOT))
49
+ from memory_lora.data_paths import EMBEDDINGS_DIR, QNA_DIR, RUNS_DIR, ensure_dirs # noqa: E402
50
+ from memory_lora.core import ( # noqa: E402
51
+ MemoryLoRAHead,
52
+ DEFAULT_ROOT_PREFIX,
53
+ discover_module_types_and_dims,
54
+ get_module_specs,
55
+ inject_lora_weights,
56
+ load_doc_rows,
57
+ load_qna_rows,
58
+ replace_with_lora,
59
+ )
60
+
61
+ DEFAULT_MODEL = "google/gemma-4-E2B"
62
+ DEFAULT_TARGET_MODULES = [
63
+ "q_proj", "k_proj", "v_proj", "o_proj",
64
+ "up_proj", "gate_proj", "down_proj",
65
+ ]
66
+
67
+
68
+ # ---------------------------------------------------------------------------
69
+ # Dataset & batching
70
+ # ---------------------------------------------------------------------------
71
+
72
+ class DocDataset:
73
+ """One example = one document with its train-split QnAs."""
74
+
75
+ def __init__(
76
+ self,
77
+ docs_by_id: Dict[str, Dict[str, Any]],
78
+ qnas_by_doc: Dict[str, List[Dict[str, str]]],
79
+ doc_ids: List[str],
80
+ max_qna_per_doc: int = 32,
81
+ seed: int = 3407,
82
+ ):
83
+ self.doc_ids = list(doc_ids)
84
+ self.docs = docs_by_id
85
+ self.qnas = qnas_by_doc
86
+ self.max_qna = max_qna_per_doc
87
+ self.rng = random.Random(seed)
88
+
89
+ def __len__(self) -> int:
90
+ return len(self.doc_ids)
91
+
92
+ def __getitem__(self, idx: int) -> Optional[Dict[str, Any]]:
93
+ d = self.doc_ids[idx]
94
+ pairs = list(self.qnas.get(d, []))
95
+ if not pairs:
96
+ return None
97
+ if len(pairs) > self.max_qna:
98
+ pairs = self.rng.sample(pairs, self.max_qna)
99
+ return {"doc_id": d, "embedding": self.docs[d]["emb"], "qnas": pairs}
100
+
101
+
102
+ def _tokenize_lm_batch(tokenizer, prefixes: List[str], targets: List[str],
103
+ max_seq_len: int = 2048,
104
+ fixed_len: bool = False) -> Dict[str, torch.Tensor]:
105
+ """Causal-LM batch with the loss masked on prefix tokens. Keeps the
106
+ rightmost prefix tokens on overflow; targets are never truncated.
107
+
108
+ fixed_len: pad every batch to EXACTLY max_seq_len instead of the
109
+ batch's own local max length. Real code prefixes vary widely (100-1024+
110
+ tokens across different repos), so per-batch padding produces a new
111
+ tensor shape almost every document. On MPS this repeatedly triggered
112
+ unbounded memory growth (observed: a run that stayed under 13GB on
113
+ homogeneous-length synthetic docs hit 70+GB and got OS-killed within
114
+ ~10 documents of real, variable-length code) -- MPS's caching allocator
115
+ does not appear to reliably reclaim/reuse blocks across many distinct
116
+ shapes the way CUDA's does. Fixing every batch to one shape avoids the
117
+ allocator ever seeing a new size after the first batch. Slightly wastes
118
+ compute on padding for short sequences; that trade is worth it for
119
+ system stability.
120
+ """
121
+ eos = tokenizer.eos_token or ""
122
+ input_ids_list: List[torch.Tensor] = []
123
+ labels_list: List[torch.Tensor] = []
124
+ for p, t in zip(prefixes, targets):
125
+ t_ids = tokenizer(t + eos, add_special_tokens=False)["input_ids"]
126
+ if not t_ids:
127
+ continue
128
+ prefix_budget = max(8, max_seq_len - len(t_ids))
129
+ p_ids_full = tokenizer(p, add_special_tokens=False)["input_ids"]
130
+ p_ids = p_ids_full[-prefix_budget:] if len(p_ids_full) > prefix_budget else p_ids_full
131
+ ids = p_ids + t_ids
132
+ labels = ([-100] * len(p_ids)) + list(t_ids)
133
+ input_ids_list.append(torch.tensor(ids, dtype=torch.long))
134
+ labels_list.append(torch.tensor(labels, dtype=torch.long))
135
+ if not input_ids_list:
136
+ return {}
137
+ local_max = max(t.size(0) for t in input_ids_list)
138
+ L = max(max_seq_len, local_max) if fixed_len else local_max
139
+ pad_id = tokenizer.pad_token_id or 0
140
+
141
+ def _lpad(x, val):
142
+ return F.pad(x, (L - x.size(0), 0), value=val)
143
+
144
+ input_ids = torch.stack([_lpad(t, pad_id) for t in input_ids_list], 0)
145
+ labels = torch.stack([_lpad(t, -100) for t in labels_list], 0)
146
+ attn_list = [torch.ones(t.size(0), dtype=torch.long) for t in input_ids_list]
147
+ attn = torch.stack([_lpad(t, 0) for t in attn_list], 0)
148
+ return {"input_ids": input_ids, "labels": labels, "attention_mask": attn}
149
+
150
+
151
+ # ---------------------------------------------------------------------------
152
+ # Eval
153
+ # ---------------------------------------------------------------------------
154
+
155
+ @torch.no_grad()
156
+ def evaluate_suite(
157
+ base_model: nn.Module, head: MemoryLoRAHead, specs, tokenizer,
158
+ doc_rows: List[Any], qnas_by_doc: Dict[str, List[Dict[str, str]]],
159
+ *, device: torch.device, max_seq_len: int = 512,
160
+ lm_micro_batch: int = 4, max_qna_per_doc: int = 32,
161
+ fixed_len: bool = False,
162
+ ) -> Dict[str, float]:
163
+ base_model.eval()
164
+ head.eval()
165
+ total_loss = 0.0
166
+ total_tokens = 0
167
+ n_docs = 0
168
+ for dr in doc_rows:
169
+ pairs = qnas_by_doc.get(dr.doc_id)
170
+ if not pairs:
171
+ continue
172
+ if len(pairs) > max_qna_per_doc:
173
+ pairs = pairs[:max_qna_per_doc]
174
+ ctx = torch.from_numpy(dr.doc_embedding).to(device).unsqueeze(0)
175
+ head_out = head(ctx)
176
+ inject_lora_weights(base_model, specs, head_out, batch_index=0)
177
+ prefixes = [p["prefix"] for p in pairs]
178
+ targets = [p["target"] for p in pairs]
179
+ for i in range(0, len(prefixes), lm_micro_batch):
180
+ j = min(i + lm_micro_batch, len(prefixes))
181
+ batch = _tokenize_lm_batch(tokenizer, prefixes[i:j], targets[i:j],
182
+ max_seq_len=max_seq_len, fixed_len=fixed_len)
183
+ if not batch:
184
+ continue
185
+ batch = {k: v.to(device) for k, v in batch.items()}
186
+ out = base_model(**batch)
187
+ loss = out.loss
188
+ ntok = (batch["labels"] != -100).sum().item()
189
+ total_loss += loss.item() * ntok
190
+ total_tokens += ntok
191
+ n_docs += 1
192
+ avg = total_loss / max(total_tokens, 1)
193
+ return {"eval_loss": avg, "n_docs": n_docs, "n_tokens": total_tokens}
194
+
195
+
196
+ # ---------------------------------------------------------------------------
197
+ # Main
198
+ # ---------------------------------------------------------------------------
199
+
200
+ def _docs_by_id(doc_rows) -> Dict[str, Dict[str, Any]]:
201
+ return {dr.doc_id: {"emb": dr.doc_embedding} for dr in doc_rows}
202
+
203
+
204
+ def _group_qnas_by_doc(rows) -> Dict[str, List[Dict[str, str]]]:
205
+ out: Dict[str, List[Dict[str, str]]] = {}
206
+ for qr in rows:
207
+ out.setdefault(qr.doc_id, []).append({"prefix": qr.prefix, "target": qr.target})
208
+ return out
209
+
210
+
211
+ def main() -> None:
212
+ ap = argparse.ArgumentParser(description=__doc__,
213
+ formatter_class=argparse.RawDescriptionHelpFormatter)
214
+ ap.add_argument("--embeddings-path", default=str(EMBEDDINGS_DIR / "doc_embeddings.parquet"))
215
+ ap.add_argument("--qna-path", default=str(QNA_DIR / "qna.jsonl"))
216
+ ap.add_argument("--output-dir", required=True)
217
+ ap.add_argument("--model-name", default=DEFAULT_MODEL)
218
+ ap.add_argument("--target-modules", nargs="+", default=DEFAULT_TARGET_MODULES)
219
+ ap.add_argument("--root-prefix", default=DEFAULT_ROOT_PREFIX)
220
+
221
+ ap.add_argument("--rank", type=int, default=16)
222
+ ap.add_argument("--alpha", type=float, default=32.0)
223
+ ap.add_argument("--head-hidden-dim", type=int, default=128,
224
+ help="Kept small deliberately -- with ~165 training "
225
+ "docs, the paper's 512-1024 hidden dim overfits "
226
+ "within ~2 epochs (see memory_lora/core.py docstring).")
227
+ ap.add_argument("--head-dropout", type=float, default=0.1)
228
+
229
+ ap.add_argument("--epochs", type=int, default=3)
230
+ ap.add_argument("--lr", type=float, default=1e-4)
231
+ ap.add_argument("--weight-decay", type=float, default=0.05)
232
+ ap.add_argument("--warmup-ratio", type=float, default=0.03)
233
+ ap.add_argument("--lr-total-steps", type=int, default=0,
234
+ help="Override the cosine LR schedule's total-step "
235
+ "target with a realistic estimate of what "
236
+ "--max-hours will actually cover, instead of "
237
+ "steps_per_epoch * epochs (which assumes the run "
238
+ "finishes a full epoch -- unrealistic at "
239
+ "tens-of-thousands-of-docs scale). 0 = use the "
240
+ "epoch-based calculation.")
241
+ ap.add_argument("--max-grad-norm", type=float, default=1.0)
242
+ ap.add_argument("--early-stop-patience", type=int, default=8,
243
+ help="Stop after this many consecutive evals with no "
244
+ "improvement on --primary-eval-suite. 0 = disabled.")
245
+
246
+ ap.add_argument("--max-qna-per-doc", type=int, default=32)
247
+ ap.add_argument("--lm-micro-batch", type=int, default=4)
248
+ ap.add_argument("--max-seq-len", type=int, default=512)
249
+ ap.add_argument("--fixed-seq-len", action="store_true", default=True,
250
+ help="Pad every batch to exactly --max-seq-len instead "
251
+ "of each batch's own local max length. See "
252
+ "_tokenize_lm_batch docstring: on MPS, varying "
253
+ "tensor shapes across many real-code documents "
254
+ "of wildly different lengths caused unbounded "
255
+ "memory growth (a run went from healthy to "
256
+ "OS-killed within ~10 documents). Costs some "
257
+ "wasted padding compute; worth it for stability.")
258
+ ap.add_argument("--no-fixed-seq-len", dest="fixed_seq_len", action="store_false")
259
+
260
+ ap.add_argument("--eval-every-steps", type=int, default=50)
261
+ ap.add_argument("--eval-suites", nargs="+", default=["cr_val", "cr_test", "ir_test"])
262
+ ap.add_argument("--limit-eval-docs", type=int, default=200,
263
+ help="Cap docs per eval suite (random sample, fixed "
264
+ "seed) for speed at real-corpus scale -- e.g. "
265
+ "cr_val alone can be 8,600+ real repo-commit "
266
+ "docs; evaluating all of them every eval cycle "
267
+ "would dominate wall-clock time. 0 = no cap "
268
+ "(matches the paper's own --limit-eval-snapshots).")
269
+ ap.add_argument("--primary-eval-suite", default="cr_val")
270
+ ap.add_argument("--log-every-iters", type=int, default=10)
271
+
272
+ ap.add_argument("--seed", type=int, default=3407)
273
+ ap.add_argument("--device", default="mps")
274
+ ap.add_argument("--dtype", default="bfloat16", choices=["bfloat16", "float16", "float32"])
275
+ ap.add_argument("--attn-implementation", default="sdpa", choices=["sdpa", "eager"])
276
+ ap.add_argument("--limit-train-docs", type=int, default=0)
277
+ ap.add_argument("--priority-doc-ids", nargs="+", default=[],
278
+ help="doc_ids to oversample within the shared "
279
+ "multi-document head (--priority-oversample "
280
+ "extra passes per epoch), instead of raising "
281
+ "global head capacity -- raising rank/hidden_dim "
282
+ "fixes within-document fact interference but "
283
+ "makes the whole corpus overfit faster (see "
284
+ "runs/full2 diagnosis); oversampling gives "
285
+ "specific documents more gradient signal without "
286
+ "changing capacity or hurting the rest.")
287
+ ap.add_argument("--priority-oversample", type=int, default=5,
288
+ help="How many times to repeat each --priority-doc-ids "
289
+ "entry per epoch's shuffled training order.")
290
+ ap.add_argument("--only-doc-ids", nargs="+", default=[],
291
+ help="Restrict training (and, if present in this set, "
292
+ "ir_test eval) to exactly these doc_ids. Used for "
293
+ "single-document capacity diagnostics -- e.g. can "
294
+ "the architecture memorize ONE document's facts "
295
+ "when not sharing hypernetwork capacity across "
296
+ "165 others?")
297
+ ap.add_argument("--gradient-checkpointing", action="store_true", default=True)
298
+ ap.add_argument("--no-gradient-checkpointing", dest="gradient_checkpointing", action="store_false")
299
+ ap.add_argument("--max-hours", type=float, default=0.0,
300
+ help="Wall-clock training budget in hours. 0 = unlimited "
301
+ "(stop only after --epochs). Checked once per doc "
302
+ "iteration; when exceeded, saves a final checkpoint "
303
+ "and stops cleanly (does not just get killed mid-write).")
304
+ ap.add_argument("--min-available-gb", type=float, default=15.0,
305
+ help="Hard safety floor: stop (with a final "
306
+ "checkpoint) if SYSTEM-WIDE available memory "
307
+ "(psutil.virtual_memory().available -- NOT this "
308
+ "process's own RSS, which undercounts MPS "
309
+ "memory on Apple Silicon) drops below this many "
310
+ "GB. Checked every 2 iterations. 0 = disabled.")
311
+ ap.add_argument("--checkpoint-every-steps", type=int, default=50,
312
+ help="Overwrite head.latest.pt every N optimizer steps "
313
+ "so a crash/kill never loses more than N steps of "
314
+ "progress. Overwrites (doesn't accumulate files), "
315
+ "so it's disk-safe even for a 3GB head. 0=disabled.")
316
+ ap.add_argument("--checkpoint-every-minutes", type=float, default=30.0,
317
+ help="Save a timestamped checkpoint every N minutes of "
318
+ "wall-clock time, independent of eval/epoch "
319
+ "boundaries. 0 = disabled (epoch-end saves only).")
320
+ ap.add_argument("--epoch-ckpt-every", type=int, default=10,
321
+ help="Only write a NEW numbered head.epN.pt every N "
322
+ "epochs (head.latest.pt still updates every "
323
+ "epoch). Each checkpoint is a full head save "
324
+ "(hundreds of MB) -- with many small/fast epochs "
325
+ "(e.g. a tiny single-document run), saving one "
326
+ "per epoch can fill the disk in minutes.")
327
+ ap.add_argument("--resume-from", default="",
328
+ help="Path to a head.*.pt checkpoint to load weights "
329
+ "from before training starts (optimizer/scheduler "
330
+ "restart fresh; only head weights are resumed).")
331
+ args = ap.parse_args()
332
+
333
+ out_dir = Path(args.output_dir)
334
+ if not out_dir.is_absolute():
335
+ out_dir = RUNS_DIR / out_dir
336
+ out_dir.mkdir(parents=True, exist_ok=True)
337
+ ensure_dirs()
338
+
339
+ device = torch.device(args.device if (args.device != "mps" or torch.backends.mps.is_available()) else "cpu")
340
+ dtype = {"bfloat16": torch.bfloat16, "float16": torch.float16, "float32": torch.float32}[args.dtype]
341
+ random.seed(args.seed)
342
+ np.random.seed(args.seed)
343
+ torch.manual_seed(args.seed)
344
+
345
+ tb = SummaryWriter(log_dir=str(out_dir / "tb"))
346
+
347
+ # ---- Load embeddings + QnAs ----
348
+ print("Loading document embeddings ...", flush=True)
349
+ all_docs = load_doc_rows(Path(args.embeddings_path))
350
+ only_ids = set(args.only_doc_ids) if args.only_doc_ids else None
351
+ train_docs = [d for d in all_docs if d.split == "train"]
352
+ if only_ids:
353
+ train_docs = [d for d in train_docs if d.doc_id in only_ids]
354
+ if args.limit_train_docs:
355
+ train_docs = train_docs[: args.limit_train_docs]
356
+ print(f" {len(train_docs)} train docs (of {len(all_docs)} total)", flush=True)
357
+
358
+ print("Loading QnAs ...", flush=True)
359
+ all_qnas = load_qna_rows(Path(args.qna_path))
360
+ if only_ids:
361
+ all_qnas = [q for q in all_qnas if q.doc_id in only_ids]
362
+ train_qnas = [q for q in all_qnas if q.qna_split == "train"]
363
+ qnas_train = _group_qnas_by_doc(train_qnas)
364
+ docs_by_id = _docs_by_id(train_docs)
365
+ doc_ids = [d for d in docs_by_id if d in qnas_train]
366
+ print(f" {sum(len(v) for v in qnas_train.values())} train QA pairs across {len(doc_ids)} docs", flush=True)
367
+
368
+ if args.priority_doc_ids and args.priority_oversample > 1:
369
+ extra = []
370
+ for pid in args.priority_doc_ids:
371
+ if pid in doc_ids:
372
+ extra.extend([pid] * (args.priority_oversample - 1))
373
+ else:
374
+ print(f" [warn] --priority-doc-ids {pid!r} not in training set, skipping", flush=True)
375
+ doc_ids = doc_ids + extra
376
+ print(f" oversampled {args.priority_doc_ids} x{args.priority_oversample} "
377
+ f"-> {len(doc_ids)} entries/epoch", flush=True)
378
+
379
+ ds = DocDataset(docs_by_id, qnas_train, doc_ids,
380
+ max_qna_per_doc=args.max_qna_per_doc, seed=args.seed)
381
+
382
+ # ---- Build LLM, discover modules, wrap them ----
383
+ print(f"Loading {args.model_name} ...", flush=True)
384
+ tokenizer = AutoTokenizer.from_pretrained(args.model_name)
385
+ if tokenizer.pad_token is None:
386
+ tokenizer.pad_token = tokenizer.eos_token
387
+ base_model = AutoModelForImageTextToText.from_pretrained(
388
+ args.model_name, torch_dtype=dtype,
389
+ attn_implementation=args.attn_implementation,
390
+ ).to(device)
391
+ base_model.eval()
392
+ for p in base_model.parameters():
393
+ p.requires_grad = False
394
+ if args.gradient_checkpointing:
395
+ base_model.config.use_cache = False
396
+ try:
397
+ base_model.gradient_checkpointing_enable(
398
+ gradient_checkpointing_kwargs={"use_reentrant": False})
399
+ print(" gradient checkpointing: ON", flush=True)
400
+ except Exception as e: # noqa: BLE001
401
+ print(f" [warn] gradient checkpointing unavailable: {e}", flush=True)
402
+
403
+ specs = get_module_specs(base_model, args.target_modules, root_prefix=args.root_prefix)
404
+ type_dims = discover_module_types_and_dims(specs)
405
+ print(f" discovered {len(specs)} target modules, {len(type_dims)} types: {sorted(type_dims)}", flush=True)
406
+ if not specs:
407
+ raise SystemExit(
408
+ f"No modules matched root_prefix={args.root_prefix!r} + "
409
+ f"{args.target_modules}. Inspect base_model.named_modules() and "
410
+ f"pass --root-prefix explicitly."
411
+ )
412
+ replace_with_lora(base_model, specs, rank=args.rank, alpha=args.alpha)
413
+
414
+ head = MemoryLoRAHead(
415
+ input_dim=train_docs[0].doc_embedding.shape[0],
416
+ type_dims=type_dims,
417
+ hidden_dim=args.head_hidden_dim,
418
+ rank=args.rank,
419
+ dropout=args.head_dropout,
420
+ ).to(device)
421
+ if args.resume_from:
422
+ ckpt = torch.load(args.resume_from, map_location=device)
423
+ head.load_state_dict(ckpt["state_dict"])
424
+ print(f" resumed head weights from {args.resume_from}", flush=True)
425
+ n_head_params = sum(p.numel() for p in head.parameters())
426
+ print(f" head params: {n_head_params / 1e6:.1f}M", flush=True)
427
+
428
+ optim = torch.optim.AdamW(head.parameters(), lr=args.lr, weight_decay=args.weight_decay)
429
+ steps_per_epoch = max(1, len(ds))
430
+ if args.lr_total_steps:
431
+ # At real-corpus scale (tens of thousands of docs), --max-hours will
432
+ # cut training off long before steps_per_epoch * epochs is reached,
433
+ # so a schedule calibrated to full-epoch coverage would barely start
434
+ # annealing from its LR peak. Calibrate to the realistically
435
+ # achievable step count instead.
436
+ total_steps = args.lr_total_steps
437
+ else:
438
+ total_steps = steps_per_epoch * args.epochs
439
+ warmup_steps = max(1, int(total_steps * args.warmup_ratio))
440
+ sched = get_cosine_schedule_with_warmup(optim, warmup_steps, total_steps)
441
+
442
+ # ---- Eval suites ----
443
+ eval_suites: Dict[str, Dict[str, Any]] = {}
444
+ print("Loading eval suites ...", flush=True)
445
+ qnas_by_doc_all = _group_qnas_by_doc(all_qnas)
446
+ qnas_held_out_by_doc = _group_qnas_by_doc([q for q in all_qnas if q.qna_split == "held_out"])
447
+ eval_rng = random.Random(args.seed)
448
+ for suite in args.eval_suites:
449
+ if suite in ("cr_val", "cr_test"):
450
+ rows = [d for d in all_docs if d.split == suite]
451
+ q_by_doc = qnas_by_doc_all
452
+ elif suite == "ir_test":
453
+ rows = train_docs
454
+ q_by_doc = qnas_held_out_by_doc
455
+ else:
456
+ continue
457
+ if args.limit_eval_docs and len(rows) > args.limit_eval_docs:
458
+ rows = eval_rng.sample(rows, args.limit_eval_docs)
459
+ eval_suites[suite] = {"doc_rows": rows, "qnas_by_doc": q_by_doc}
460
+ n_q = sum(len(q_by_doc.get(d.doc_id, [])) for d in rows)
461
+ print(f" {suite}: {len(rows)} docs, {n_q} qnas", flush=True)
462
+
463
+ # ---- Train ----
464
+ metrics_log: List[Dict[str, Any]] = []
465
+ best_eval = float("inf")
466
+ global_step = 0
467
+ t0 = time.time()
468
+ last_ckpt_wall = t0
469
+ budget_seconds = args.max_hours * 3600.0 if args.max_hours > 0 else float("inf")
470
+ ckpt_interval_seconds = args.checkpoint_every_minutes * 60.0 if args.checkpoint_every_minutes > 0 else float("inf")
471
+ stop_training = False
472
+ patience_counter = 0
473
+ for epoch in range(args.epochs):
474
+ if stop_training:
475
+ break
476
+ order = list(range(len(ds)))
477
+ random.shuffle(order)
478
+ head.train()
479
+ running_loss, running_n = 0.0, 0
480
+ for it, di in enumerate(order):
481
+ now = time.time()
482
+ if now - t0 >= budget_seconds:
483
+ print(f" [budget] {args.max_hours:.2f}h training budget reached "
484
+ f"(epoch {epoch}, it {it}/{len(order)}) -- stopping.", flush=True)
485
+ stop_training = True
486
+ break
487
+ if now - last_ckpt_wall >= ckpt_interval_seconds:
488
+ mins = int((now - t0) / 60)
489
+ p = _save_ckpt(out_dir, head, type_dims, args, name=f"t{mins:04d}m")
490
+ _save_ckpt(out_dir, head, type_dims, args, name="latest")
491
+ print(f" [ckpt] periodic ({args.checkpoint_every_minutes:.0f}min interval) -> {p}", flush=True)
492
+ last_ckpt_wall = now
493
+ if args.min_available_gb > 0 and it % 2 == 0:
494
+ # IMPORTANT: this checks SYSTEM-WIDE available memory
495
+ # (psutil.virtual_memory), not this process's own RSS.
496
+ # psutil.Process().memory_info().rss -- like `ps -o rss` --
497
+ # does NOT reliably capture MPS/GPU-resident allocations
498
+ # on Apple Silicon: a run was observed at 55-83GB actual
499
+ # usage (per `top`'s MEM column, corroborated by system
500
+ # vm_stat showing genuine memory exhaustion) while RSS
501
+ # reported under 1GB the whole time. System-wide available
502
+ # memory is the metric that's actually reliable here.
503
+ available_gb = psutil.virtual_memory().available / 1e9
504
+ if available_gb < args.min_available_gb:
505
+ print(f" [safety] system available memory {available_gb:.1f}GB "
506
+ f"below --min-available-gb {args.min_available_gb:.1f}GB "
507
+ f"(epoch {epoch}, it {it}) -- saving and stopping to "
508
+ f"protect system stability.", flush=True)
509
+ _save_ckpt(out_dir, head, type_dims, args, name="latest")
510
+ stop_training = True
511
+ break
512
+ sample = ds[di]
513
+ if sample is None:
514
+ continue
515
+ ctx = torch.from_numpy(sample["embedding"]).to(device).unsqueeze(0)
516
+ qnas = sample["qnas"]
517
+ prefixes = [q["prefix"] for q in qnas]
518
+ targets = [q["target"] for q in qnas]
519
+ micro_batches = []
520
+ for i in range(0, len(prefixes), args.lm_micro_batch):
521
+ j = min(i + args.lm_micro_batch, len(prefixes))
522
+ b = _tokenize_lm_batch(tokenizer, prefixes[i:j], targets[i:j],
523
+ max_seq_len=args.max_seq_len, fixed_len=args.fixed_seq_len)
524
+ if b:
525
+ micro_batches.append({k: v.to(device) for k, v in b.items()})
526
+ if not micro_batches:
527
+ continue
528
+ n_tok_seen, loss_acc = 0, 0.0
529
+ for mb_idx, batch in enumerate(micro_batches):
530
+ if args.min_available_gb > 0 and mb_idx % 3 == 0:
531
+ # Same system-wide check as the per-document one below,
532
+ # but INSIDE the micro-batch loop too: observed runaway
533
+ # growth can blow past a safe threshold within a
534
+ # single document's micro-batches, before the
535
+ # per-document check would ever fire.
536
+ available_gb = psutil.virtual_memory().available / 1e9
537
+ if available_gb < args.min_available_gb:
538
+ print(f" [safety] system available memory {available_gb:.1f}GB "
539
+ f"below --min-available-gb {args.min_available_gb:.1f}GB "
540
+ f"mid-document (epoch {epoch}, it {it}, micro-batch "
541
+ f"{mb_idx}) -- saving and stopping immediately.", flush=True)
542
+ _save_ckpt(out_dir, head, type_dims, args, name="latest")
543
+ stop_training = True
544
+ break
545
+ head_out = head(ctx)
546
+ inject_lora_weights(base_model, specs, head_out, batch_index=0)
547
+ out = base_model(**batch)
548
+ ntok = (batch["labels"] != -100).sum().item()
549
+ loss = out.loss * ntok
550
+ loss.backward()
551
+ loss_acc += loss.detach().item()
552
+ n_tok_seen += ntok
553
+ del head_out, out, loss
554
+ if stop_training:
555
+ break
556
+ if n_tok_seen == 0:
557
+ continue
558
+ if device.type == "mps" and it % 5 == 0:
559
+ # MPS's caching allocator is markedly less aggressive about
560
+ # returning freed blocks to the OS than CUDA's -- on a
561
+ # unified-memory Mac (CPU and GPU share physical RAM,
562
+ # unlike a discrete-GPU box with isolated VRAM) that cache
563
+ # growth directly threatens the whole system, not just this
564
+ # process. Without this, a real-corpus run OOM'd the OS
565
+ # itself (83GB RSS, process state "stuck", heavy swapping)
566
+ # within the first ~10 minutes.
567
+ torch.mps.empty_cache()
568
+
569
+ torch.nn.utils.clip_grad_norm_(head.parameters(), args.max_grad_norm)
570
+ optim.step()
571
+ sched.step()
572
+ optim.zero_grad(set_to_none=True)
573
+ global_step += 1
574
+
575
+ if args.checkpoint_every_steps > 0 and global_step % args.checkpoint_every_steps == 0:
576
+ _save_ckpt(out_dir, head, type_dims, args, name="latest")
577
+
578
+ running_loss += loss_acc
579
+ running_n += n_tok_seen
580
+ if it % max(1, args.log_every_iters) == 0:
581
+ avg = running_loss / max(running_n, 1)
582
+ elapsed = (time.time() - t0) / 60
583
+ print(f"[ep{epoch} it{it}/{len(order)} step{global_step}] "
584
+ f"loss={avg:.4f} lr={sched.get_last_lr()[0]:.2e} elapsed={elapsed:.1f}m", flush=True)
585
+ tb.add_scalar("train/loss", avg, global_step)
586
+ tb.add_scalar("train/lr", sched.get_last_lr()[0], global_step)
587
+ running_loss, running_n = 0.0, 0
588
+
589
+ if (args.eval_every_steps > 0 and global_step > 0
590
+ and global_step % args.eval_every_steps == 0
591
+ and it + 1 != len(order)):
592
+ # The `it + 1 != len(order)` guard skips a redundant eval when
593
+ # eval_every_steps happens to equal (a multiple of) steps-per-
594
+ # epoch -- the unconditional end-of-epoch eval below would
595
+ # otherwise double-count this exact step in the early-stop
596
+ # patience counter every epoch.
597
+ prev_best = best_eval
598
+ best_eval = _do_eval(args, base_model, head, specs, tokenizer, eval_suites,
599
+ device, out_dir, metrics_log, best_eval, global_step, epoch, tb)
600
+ patience_counter = 0 if best_eval < prev_best else patience_counter + 1
601
+ if args.early_stop_patience > 0 and patience_counter >= args.early_stop_patience:
602
+ print(f" [early-stop] no improvement on {args.primary_eval_suite} for "
603
+ f"{patience_counter} evals -- stopping.", flush=True)
604
+ stop_training = True
605
+ break
606
+
607
+ _save_ckpt(out_dir, head, type_dims, args, name="latest")
608
+ if epoch % max(1, args.epoch_ckpt_every) == 0:
609
+ ep_path = _save_ckpt(out_dir, head, type_dims, args, name=f"ep{epoch}")
610
+ print(f" [ckpt] end-of-epoch ep{epoch} -> {ep_path}", flush=True)
611
+ else:
612
+ print(f" [ckpt] end-of-epoch ep{epoch} -> (latest.pt only)", flush=True)
613
+ prev_best = best_eval
614
+ best_eval = _do_eval(args, base_model, head, specs, tokenizer, eval_suites,
615
+ device, out_dir, metrics_log, best_eval, global_step, epoch, tb,
616
+ end_of_epoch=True)
617
+ patience_counter = 0 if best_eval < prev_best else patience_counter + 1
618
+ if args.early_stop_patience > 0 and patience_counter >= args.early_stop_patience:
619
+ print(f" [early-stop] no improvement on {args.primary_eval_suite} for "
620
+ f"{patience_counter} evals -- stopping.", flush=True)
621
+ stop_training = True
622
+
623
+ tb.close()
624
+ print(f"\nTraining done. Best primary eval = {best_eval:.4f}", flush=True)
625
+
626
+
627
+ def _save_ckpt(out_dir: Path, head: MemoryLoRAHead, type_dims, args, name: str = "latest") -> Path:
628
+ out = out_dir / f"head.{name}.pt"
629
+ torch.save({
630
+ "state_dict": head.state_dict(),
631
+ "config": head.config_dict(),
632
+ "type_dims": type_dims,
633
+ "args": vars(args),
634
+ }, out)
635
+ return out
636
+
637
+
638
+ def _do_eval(args, base_model, head, specs, tokenizer, eval_suites, device, out_dir,
639
+ metrics_log, best_eval, global_step, epoch, tb, end_of_epoch: bool = False) -> float:
640
+ suite_metrics: Dict[str, Dict[str, float]] = {}
641
+ for name, suite in eval_suites.items():
642
+ m = evaluate_suite(base_model, head, specs, tokenizer,
643
+ suite["doc_rows"], suite["qnas_by_doc"],
644
+ device=device, max_seq_len=args.max_seq_len,
645
+ lm_micro_batch=args.lm_micro_batch,
646
+ max_qna_per_doc=args.max_qna_per_doc,
647
+ fixed_len=args.fixed_seq_len)
648
+ suite_metrics[name] = m
649
+ print(f" [eval {name}] step={global_step} loss={m['eval_loss']:.4f} "
650
+ f"docs={m['n_docs']} tok={m['n_tokens']}", flush=True)
651
+ tb.add_scalar(f"eval/{name}_loss", m["eval_loss"], global_step)
652
+ primary = suite_metrics.get(args.primary_eval_suite)
653
+ primary_loss = primary["eval_loss"] if primary else float("inf")
654
+ row = {"step": global_step, "epoch": epoch, "end_of_epoch": end_of_epoch,
655
+ "eval_loss": primary_loss, "suites": suite_metrics}
656
+ metrics_log.append(row)
657
+ (out_dir / "metrics.jsonl").open("a").write(json.dumps(row) + "\n")
658
+ if primary_loss < best_eval:
659
+ best_eval = primary_loss
660
+ p = _save_ckpt(out_dir, head, head.type_dims, args, name="best")
661
+ print(f" [ckpt] best updated -> {p} (loss={primary_loss:.4f})", flush=True)
662
+ _save_ckpt(out_dir, head, head.type_dims, args, name="latest")
663
+ head.train()
664
+ return best_eval
665
+
666
+
667
+ if __name__ == "__main__":
668
+ main()