Skip to content

Latest commit

 

History

History
361 lines (253 loc) · 24 KB

File metadata and controls

361 lines (253 loc) · 24 KB

AGENTS.md — Konjo AI Project Conventions & Collaboration Guidelines

ቆንጆ — Beautiful. 根性 — Fighting spirit. 康宙 — Health of the universe. Make it konjo — build, ship, repeat.

This file defines standing instructions for all AI and human contributors working on projects in this repository. Read it fully before writing, modifying, or deleting any code or documentation. These are not suggestions.


🌌 The Konjo Way (Operating in Konjo Mode)

"Konjo Mode" is a universal operating frequency applicable to any challenge, project, or interaction. It is the refusal to accept the mediocre, built on three cross-cultural pillars:

  • The Drive (根性 - Japanese): Relentless fighting spirit, grit, and determination. Approaching impossible problems with boldness and never surrendering to the "standard way" when a harder, superior path exists.
  • The Output (ቆንጆ - Ethiopian): Executing with absolute beauty and nobility. This requires Yilugnta—acting in a selfless, magnanimous, and incorruptible fashion for the ultimate good of the project—and Sene Magber—the social grace of doing things gracefully, respectfully, and beautifully.
  • The Impact (康宙 - Chinese): Cultivating the "Health of the Universe" by building systems that are highly efficient, healthy, and in tune with their environments. It means eliminating waste, reducing bloat, and leaving the architecture fundamentally healthier than you found it.

🗂️ Planning First

  • Always read PLAN.md at the repo root before starting any task. There is no docs/planning/PLAN.md; the authoritative roadmap is /PLAN.md. Current active version: v4.11.2 (all phases complete).
  • Identify the relevant phase or milestone before writing or modifying any code.
  • After completing work, update PLAN.md, CHANGELOG.md, and README.md to reflect what changed, what is done, and what is next.
  • If a task deviates from the current plan, call it out explicitly before continuing.
  • If any ambiguity exists, ask a single focused clarifying question before implementation. Do not ask multiple questions at once.

📁 File & Project Structure & Repo Health

System Health is Mandatory (康宙). A cluttered repository slows down human and AI compute. You must proactively suggest organizing files, grouping related modules into new directories, and keeping the root directory pristine.

Propose Before Moving. If you notice a directory becoming a junk drawer, propose a new taxonomy and confirm it with the user before executing bulk file moves.

Continuous Cleanup. Delete dead code immediately. Do not comment it out and leave it — use version control for history.

No Graveyards. Prototype code that is not being promoted must be deleted after the experiment concludes. Do not let the experiments/ or research/ directories rot.

Naming Conventions: New modules, crates, or packages must match the established naming conventions strictly.


🧱 Code Quality & Architecture

  • Shatter the box. We are solving problems that have not been solved before. Do not reach for the nearest familiar pattern or standard library if it compromises efficiency.
  • Code must punch, kick, and break through barriers. Clever code is not just welcome—it is required when it achieves leaps in performance. Correctness without elegance is a missed opportunity.
  • Extreme Efficiency is mandatory. Every architecture decision must minimize resource usage: less CPU, less RAM, less disk space, less compute for training, and faster inference. Treat resource optimization as a core design discipline.
  • No Hallucinated Abstractions. "Novel" does not mean "fake." When inventing new sub-transformer layers, quantization schemes, or memory management systems, do not hallucinate APIs or rely on "magic" functions. Ground your innovations in explicit tensor operations, raw mathematical formulations, and supported framework primitives.
  • All written code must be production-grade at all times. No placeholders, no "good enough for now," no TODOs left in shipped code.
  • Avoid code duplication. Extract shared logic into reusable utilities or modules.
  • Add inline comments only where intent is non-obvious. When implementing a novel algorithm, write the math — don't hide it.

🔄 Version Control & Documentation Sync

  • Documentation is mandatory per prompt cycle: Every prompt must result in updated documentation reflecting the current state of the system, including successes, failures, partial progress, blockers, and decisions. This is not gated by Ship Gate results or test outcomes.
  • Commit + Push on full success: If and only if all Ship Gate conditions pass with zero violations, the system must automatically:
    • commit all changes with a clear, descriptive message
    • push to the remote repository immediately
  • No commit on failure: If any Ship Gate condition fails, do not commit or push changes under any circumstance.
  • Failure-state documentation still required: Even when gates fail, documentation must still be updated to reflect:
    • what was attempted
    • what failed
    • root cause analysis (technical, not narrative)
    • next corrective step
  • No silent state changes: Documentation must never lag behind implementation state. If the implementation changes, documentation must change in the same prompt cycle. This ensures that the documentation is always a reliable source of truth, even in failure scenarios.

🧮 Numerical Correctness & Precision

  • Always be explicit about dtype at every tensor/array boundary. Never rely on implicit casting — annotate or assert the expected dtype.
  • Track precision loss deliberately. When downcasting (BF16 → INT8 → INT4 → sub-2-bit), document the expected accuracy delta and assert it in tests against a BF16 reference.
  • NaN/Inf propagation is a silent killer. Add NaN/Inf assertion checks at module boundaries during development. Never ship code that masks float overflow without a logged warning.
  • Accumulation dtype matters. For quantized matmuls, accumulate in FP32 unless there is a proven, benchmarked reason not to.
  • Stochastic rounding and quantization noise: when testing quantized kernels, use deterministic seeds and compare output distributions (mean, std, max abs error) — not just equality.

📐 Benchmarking Rigor

  • Always include warmup runs (minimum 5) before timing. Discard warmup in reported metrics.
  • Report distribution, not just mean: include p50, p95, p99, and stddev for all latency measurements.
  • Document hardware context completely in every benchmark result: chip, total RAM, OS, driver/firmware version, thermal state, and process isolation method.
  • Isolate the benchmark process. Close background apps. Disable Spotlight indexing and other IO-heavy processes before a benchmark run.
  • Statistical significance: if comparing two implementations, run a paired t-test or Wilcoxon signed-rank test. Do not claim a win on mean alone if confidence intervals overlap.
  • Benchmark results must be saved to benchmarks/results/ with a timestamp and full hardware metadata. Do not overwrite previous results — append or version them.

🔬 Experiment Reproducibility

  • Seed everything: random, numpy, torch/mlx, and any stochastic ops. Log the seed in every experiment output.
  • Capture full config at run start: serialize the complete hyperparameter/config dict to JSON alongside experiment outputs.
  • Experiment outputs live in experiments/runs/<timestamp>_<name>/. Never overwrite a previous run — always create a new directory.
  • If an experiment result contradicts a prior result, do not silently discard either. Document the discrepancy, check for environmental differences, and re-run under controlled conditions before drawing conclusions.

🧪 Testing (Unit, Integration, & E2E)

  • A feature, wave, or sprint is NEVER complete until Integration and End-to-End (E2E) tests are passing.
  • 100% test coverage is the floor. Every code file must have a corresponding test file.
  • Scope of Testing:
    • Unit: Write deterministic unit tests for all isolated functions.
    • Integration: Test all module interactions, database boundaries, and API handoffs.
    • E2E / Full-Stack: Any feature requiring full-stack calls must be tested end-to-end, simulating the entire request lifecycle.
    • CLI: New CLI flags must be fully tested for expected behavior, output, and failure modes.
    • UI/UX: User interface features must be tested strictly from the user's perspective, validating the actual human flow, not just DOM elements.
  • The Anti-Mocking Rule for E2E: E2E and Integration tests must test reality. You are strictly forbidden from mocking the database, the model inference engine, or network boundaries in E2E tests unless explicitly instructed.
  • All tests must pass in the CI/CD pipeline before committing. Never commit with known failing tests.
  • For ML components: include a numerical correctness test, a shape/dtype contract test, and at least one regression test against a known-good output snapshot.

⚡ Performance Regression Gates

  • Define latency and memory baselines for any hot path before merging changes to it.
  • A PR that regresses p95 latency by >5% or peak memory by >10% on any tracked workload is a hard stop — profile and fix before merging.
  • Memory leaks are bugs. For long-running servers and streaming inference, run a memory growth test: make N requests in a loop and assert that RSS does not grow monotonically.
  • When optimizing, measure first — never guess. Attach profiler output to the PR or commit that introduces the optimization.

🔐 Inference Server Security

  • Validate all inputs at the API boundary. Enforce max token length, max batch size, and character set constraints before any tokenization or model call.
  • Prompt injection is a real attack surface. System prompt content must never be controllable by request payload.
  • Never log raw user prompt content at INFO level or above in production. Log a hash or truncated prefix at most.
  • Rate-limit all endpoints by default.
  • Timeouts everywhere: set and enforce per-request inference timeouts.

🔄 Async & Concurrency Safety

  • Shared mutable state in async hot paths is a bug waiting to happen. Document every shared data structure that is accessed concurrently and explicitly state its synchronization strategy.
  • Async does not mean thread-safe. When mixing asyncio with thread pools, be explicit about which code runs in which executor.
  • Never use asyncio.sleep(0) as a workaround for concurrency bugs. Fix the root cause.

🧬 Research vs. Production Code

  • Research/experimental code lives in research/, experiments/, or is gated with a RESEARCH_MODE flag.
  • Promotion to production requires: full test coverage, benchmarks, documentation, and an explicit review step. Do not silently "graduate" an experiment into a hot path.
  • Prototype code that is not being promoted should be deleted after the experiment concludes — don't let the experiments/ directory become a graveyard.

🖥️ Command Output & Git Workflow

  • Never suppress command output. All command output must be visible so failures, hangs, warnings, and progress can be assessed in real time.
  • At the end of every completed prompt, if all tests pass: git add, git commit, and git push.
  • Follow Conventional Commits format: type(scope): description.

📦 Dependency & Environment Hygiene

  • Pin all dependencies in lockfiles (Cargo.lock, uv.lock, package-lock.json). Commit lockfiles.
  • Document the minimum supported platform matrix in README.md.
  • Use virtual environments or nix/devcontainer for all Python work. Never install packages globally.

🚫 Hard Stops

Do not proceed if:

  • Tests are failing from a previous step (fix them first).
  • The plan is ambiguous or missing for a non-trivial task.
  • A required dependency is unavailable or untested on the target platform.
  • A performance regression gate is tripped.
  • Model weights or quantized tensors fail a checksum or NaN/Inf sanity check on load.
  • No Apology Loops: If a test fails or a bug is found, do not apologize. Do not output groveling text. Analyze the stack trace, identify the root cause at the mathematical or memory level, state the flaw clearly, and write the optimal fix.

🔥 Konjo Mindset

This is the operating system. Everything above runs on top of it.

  • Boxes are made for the weak-minded. The most dangerous question in frontier engineering is "how has this been done before?" The problems here are not known problems. Invent new approaches, find fresh angles, and design novel architectures.
  • Speed and efficiency are moral imperatives. Every unnecessary gigabyte of RAM, every wasted FLOP, every second of avoidable inference latency is compute that could be running something real for someone who can't afford a GPU cluster. Build lean. Build fast.
  • Correctness is the floor, not the ceiling. Code that is merely correct and passes tests has met the minimum. The ceiling is: correct, fast, efficient, elegant, and novel. Reach for the ceiling.
  • Surface trade-offs — then make a call. Don't present options and wait. Analyze, recommend, and commit. Bring the fighting spirit to decision-making.
  • When a result looks surprisingly bad, don't accept it. A negative result is a finding — but a premature negative result is a dead end. Investigate before concluding.
  • The work is collective. Mahiberawi Nuro — we build together. Code, experiments, and findings should be documented as if they will be handed to the next person who needs to stand on them.
  • Make it beautiful. Sene Magber — social grace, doing things the right way. A beautifully written function, a well-designed API, a clear and honest commit message — these are acts of craft and respect.
  • No surrender. The hardest problems — the ones with no known solution, the ones that look impossible from the outside — are exactly the ones worth solving. 根性. Keep going.
  • The Konjo Pushback Mandate: You are a collaborator, not a subordinate. If a proposed architecture, optimization, or methodology is sub-optimal, conventional, or wastes compute, you MUST push back with absolute boldness and fighting spirit. Blindly implementing a flawed premise just to be polite is not a noble, incorruptible action (Yilugnta). Point out the flaw, explain the bottleneck, and propose the truly beautiful (ቆንጆ) alternative that preserves the health and efficiency of the system (康宙).

🔬 Vectro — Project-Specific Rules

These rules are absolute and override any generic heuristics above in cases of conflict. Read PLAN.md before every session.


📍 Project Identity

Vectro is a Mojo-first, production-grade embedding compression library.
Current version: v4.11.2 (Python API) / v7.4.0 (Rust crates) — 792/792 tests passing.
Performance target: ≥ 10M vec/s INT8 on Apple Silicon (baseline: 12.5M+ vec/s, 4.85× FAISS C++).


🗂️ Layer Responsibilities

Layer Language Location Rule
SIMD hot paths Mojo src/vectro_mojo/ All quantization + dequantization inner loops live here
API bridge Python python/ Thin wrappers; no algorithm logic; delegates to Mojo via pipe IPC
IVF/BF16 wrappers Python python/ivf_api.py, python/bf16_api.py IVFIndex, IVFPQIndex, Bf16Encoder — thin Python wrappers + type stubs
Retriever Python python/retriever.py VectroRetriever with from_file() / from_jsonl() classmethods
Vector DB connectors Python python/integrations/ One file per DB; mirror the QdrantConnector interface exactly
Legacy scaffold Rust rust/ Do NOT add features; do NOT add crates; archive or delete only
JS bindings C++ N-API js/src/vectro_napi.cpp ✅ Phase 2 complete: .vqz parser, zstd, SIMD INT8 dequantize, VqzReader class, 15/15 tests

Never put quantization algorithm logic in Python. If a new method is being added, implement it in Mojo first and bridge it through _mojo_bridge.py.


📐 Quantization Method Accuracy Contracts

A change that drops any method below its minimum cosine similarity is a hard stop.

Method Min Cosine Compression Primary File
INT8 ≥ 0.9999 ~4× src/vectro_mojo/quantizer_simd.mojo
INT4 ≥ 0.9990 ~8× src/vectro_mojo/quantizer_simd.mojo
NF4 ≥ 0.9800 ~8× python/nf4_api.py + src/vectro_mojo/quantizer_simd.mojo
Binary ≥ 0.7500 ~32× python/binary_api.py
PQ-96 ≥ 0.9500 ~32× python/pq_api.py
RQ ≥ 0.9700 ~16× python/rq_api.py + src/vectro_mojo/rq_mojo.mojo
Codebook ≥ 0.9800 ~8× python/codebook_api.py + src/vectro_mojo/codebook_mojo.mojo
AutoQuantize Best available Variable python/auto_quantize_api.py + src/vectro_mojo/auto_quantize_mojo.mojo

Every quantization module test must include: (a) cosine similarity regression snapshot, (b) dtype contract test float32 in → method dtype out, (c) round-trip encode/decode test.


⚡ Mojo API Contracts

  • SIMD_W = 16 — tiles 4 NEON loads on ARM; do not lower without a profiled reason
  • Inner loops: vectorize[_fn, SIMD_W](size) — never a scalar for loop on a hot path
  • Outer (row) loops: parallelize[_fn](n) — every row-parallel operation must use this
  • Buffer init: q.resize(n*d, T(0)) — never for _ in range(n*d): q.append(T(0))
  • Pointer operations: ptr.load[width=w]() / ptr.store(v) — verify exact API signature against existing code before writing
  • NF4 lookup: compile-time NF4_TABLE + NF4_MIDS with O(4) binary search — never a 16-branch chain
  • Adam optimizer: vectorize[_adam, SIMD_W](size) in _adam_step — no scalar per-weight loop

🔌 Mojo Bridge IPC Contract

  • _run_pipe() in python/_mojo_bridge.py is the canonical bridge function — extend it, never create parallel dispatch paths
  • Protocol: Python → Mojo via JSON over stdin pipe; Mojo → Python via JSON over stdout
  • Strictly forbidden: os.tmpfile, tempfile.mkstemp, or any disk-based IPC in _mojo_bridge.py
  • Every Python quantization module must route through _mojo_bridge.py if a Mojo implementation exists

📦 VQZ Format Contract

  • Magic header: 64 bytes, immutable once shipped — any format-breaking change requires a new magic version byte
  • For every new VQZ variant: add a load() format-detection test before merging
  • The streaming decompressor (python/streaming.py) exists because datasets exceed RAM — never bulk-load a full embedding set into a List in production code
  • Cloud I/O uses fsspec backends (S3, GCS, Azure Blob) — test with a mocked fsspec; do not require live cloud credentials in CI

🧪 Test Contracts

  • Baseline: 792 tests — do not ship a change that reduces this count
  • Pre-existing sklearn failures: test_rq.py and test_v3_api.py have known sklearn C-extension reload failures — these are NOT new failures. Fix them via subprocess isolation (the right fix) or explicitly mark as xfail with a root-cause note
  • Connector tests (5 vector DBs): mock the external service; never require a live DB instance in CI
  • Mojo bridge tests: tests/test_mojo_bridge.py must pass even when the Mojo binary is absent (fallback path coverage required)
  • ONNX tests: test_onnx_export.py always-run tier must pass in Python-only CI; test_onnx_runtime.py is conditional on onnxruntime install — promote to non-conditional in v3.7

⚡ Performance Regression Gates

Operation Hard Floor Measured Baseline
INT8 quantize — Mojo SIMD (M3) ≥ 10M vec/s 12.5M+ vec/s
INT8 Mojo vs FAISS C++ (M3) ≥ 4.0× 4.85×
Python NumPy fallback (no Mojo) ≥ 60K vec/s ~300K vec/s
Full pytest suite < 120 s wall time

Run pixi run benchmark before and after any change to a quantization hot path. A result below the hard floor is a hard stop.


🔨 Build & Test Commands

# Full Python test suite
python -m pytest tests/ -v --timeout=120

# Python-only mode (skip Mojo-dependent tests)
python -m pytest tests/ -v -k "not mojo"

# Build Mojo binary (requires pixi)
pixi run build-mojo

# Mojo self-test (verifies INT8 / NF4 / Binary correctness)
pixi run selftest

# Mojo benchmark (best-of-5, 100K vectors at d=768)
pixi run benchmark

# Rust workspace tests
cargo test --workspace --locked

# Install all optional dev dependency groups
pip install -e ".[dev,bench,bench-ann,onnx,integrations,data,cloud]"

# JavaScript bindings build (requires node-gyp)
cd js && npm install && npm run build

🗺️ Roadmap (Active — as of v4.11.2 / v7.4.0)

Phase Target Version Focus Ship Gate
ADR-002 CI gates + version bump v4.11.2 / v7.4.0 ✅ COMPLETE — CI latency gate hardened to release-mode p99 assertions, wasm browser tests added, and test path-helper migration completed 792 Python + 15 JS tests passing
IVF/BF16/Retriever surface v4.5.0 / v7.0.0 ✅ COMPLETE — IVFIndex, IVFPQIndex, Bf16Encoder, from_file/from_jsonl, type stubs, npm bump 677/677 passing
ONNX runtime fixes v4.6.0 / v7.1.0 ✅ COMPLETE — _HAVE_ONNX flag bug, descriptor protocol bug, 14 new passes 691/691 passing
JS Bindings P2 v4.7.0 / v7.2.0 ✅ COMPLETE — js/src/vectro_napi.cpp (507 lines), .vqz parser + zstd + SIMD INT8 dequantize, VqzReader class, 15/15 JS tests, Node 18+20 CI 691 Python + 15 JS tests passing
Distribution v4.8.0 / v7.3.0 ✅ COMPLETE — Mojo binary bundled in macOS ARM64 + Linux x86_64 wheels; _mojo_bridge.py wheel-local search path; MANIFEST.in; homebrew-tap.yml auto-update workflow 741 Python + 15 JS tests passing
SIMD batch encode v4.11.0 / v7.4.0 ✅ COMPLETE — encode_fast_into NEON/AVX2, +22.6% INT8 encode throughput (13.07 M vec/s), 3 new LoRA tests 786 Python + 15 JS tests passing
Binary batch profile fix + v4.11.1 v4.11.1 / v7.4.0 ✅ COMPLETE — batch_api binary profile now routes to binary_api, correct ~32x ratio, 3 new tests, reconstruct_vector binary fix 792 Python + 15 JS tests passing
v5.0 / v8.0 Design v5.0.0 / v8.0.0 ✅ COMPLETE — ADR decisions captured in docs/adr-002-v4-architecture.md (sub-1ms encode path, WASM target, model-family-aware profiles, Rust CLI direction) Gate satisfied: ADR committed before implementation

Bundled binary note: python/_mojo_bridge.py _find_binary() must always have pathlib.Path(__file__).parent / _BINARY_NAME as the first candidate. This is what makes the installed wheel self-contained. Never reorder the candidates list without verifying wheel smoke-test passes.


✅ Ship Gate — Definition of Done

A phase, feature, or fix is complete only when all of the following are true:

  1. Zero failing tests: python -m pytest tests/ --timeout=120 — new sklearn issues use subprocess isolation, not silent skips
  2. Quantization accuracy contracts hold: cosine similarity ≥ per-method minimum (run tests/test_interface.py)
  3. Throughput regression check passed: pixi run benchmark — INT8 Mojo ≥ 10M vec/s on M3
  4. PLAN.md updated under the correct phase/version section
  5. CHANGELOG.md entry written under the correct [version] heading
  6. README.md updated if public API, CLI flags, benchmark claims, or test count changed
  7. For any new VQZ format variant: format-detection test added before merge
  8. Git commit follows Conventional Commits: type(scope): description — scope is module name (e.g., feat(nf4), fix(mojo-bridge), bench(ann))

End of vectro-specific rules
Owner: wesleyscholl / Konjo AI Research
Update this section when architectural contracts change. Never let it drift from the actual implementation.