AkurAI Build
Menu

AkurAI-Build

public

Latest change db3fe9caf9ed5f9da4cf8a8543f0a65b73921a53 - plan: enforce suite deployment through AkurAI Build by Ólafur Búi Ólafsson

#!/usr/bin/env python3
"""Self-checks for pm.py. Run: python3 test_pm.py"""
import shutil
import sys
import tempfile
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent))
import pm

SRC = Path(__file__).resolve().parent


def main():
    with tempfile.TemporaryDirectory() as tmp:
        root = Path(tmp) / "proj"
        root.mkdir()
        for d in (".plan", ".tasks", ".docs", ".memories", ".codebase_index"):
            shutil.copytree(SRC / d, root / d)
        pm.ROOT = root

        # new task lands with defaults and shows up in the index
        pm.new("task", "ship-it")
        task = root / ".tasks/ship-it.md"
        text = task.read_text()
        assert pm.field(text, "Status") == "backlog"
        assert pm.field(text, "Updated") == pm.today()
        assert pm.field(text, "Epic") == "none"
        assert "ship-it.md" in (root / ".tasks/TASKS.md").read_text()

        # status change updates file and moves it between index sections
        pm.set_status("ship-it", "active")
        assert pm.field(task.read_text(), "Status") == "active"
        idx = (root / ".tasks/TASKS.md").read_text()
        assert idx.index("## Active") < idx.index("ship-it.md") < idx.index("## Backlog")

        # epic appears in PLAN.md; task can link to it
        pm.new("epic", "v1")
        assert "| v1 | planned |" in (root / ".plan/PLAN.md").read_text()
        pm.new("task", "epic-task", epic="v1")
        assert "(../.plan/epics/v1.md)" in (root / ".tasks/epic-task.md").read_text()

        # doc appears in docs index with its summary
        pm.new("doc", "setup")
        assert "setup.md" in (root / ".docs/INDEX.md").read_text()

        # clean tree validates
        assert pm.validate() == [], pm.validate()

        # log prepends a dated status line
        pm.log("did a thing")
        mem = root / ".memories/MEMORIES.md"
        assert f"- {pm.today()} — did a thing" in mem.read_text()

        # broken link is caught
        bad = root / ".docs/bad.md"
        bad.write_text("# Bad\n\n## Summary\nx\n\nsee [gone](nope.md)\n")
        pm.sync()
        assert any("nope.md" in e for e in pm.validate())
        bad.unlink()
        pm.sync()

        # index drift is caught
        manual = root / ".tasks/manual.md"
        manual.write_text(task.read_text())
        assert any("pm sync" in e for e in pm.validate())
        manual.unlink()
        pm.sync()

        # secret values in memories are caught
        mem.write_text(mem.read_text() + "\npassword: hunter2hunter2\n")
        assert any("secret value" in e for e in pm.validate())
        mem.write_text(mem.read_text().replace("\npassword: hunter2hunter2\n", ""))

        # chunking: one chunk per ## section, id carries file + heading
        doc = root / ".docs/arch.md"
        doc.write_text("# Arch\n\n## Summary\nintro\n\n## Database\npostgres lives here\n")
        ids = dict(pm.chunks())
        assert ".docs/arch.md::Database" in ids
        assert "postgres lives here" in ids[".docs/arch.md::Database"]

        # code chunking: line-windowed blocks with file:line ids, junk dirs skipped
        src = root / "src"
        src.mkdir()
        (src / "billing.py").write_text(
            "def calculate_invoice_tax(amount, region):\n    return amount * RATES[region]\n")
        (root / "node_modules").mkdir()
        (root / "node_modules/junk.js").write_text("var x = 1\n")
        code = dict(pm.code_chunks())
        assert "src/billing.py:L1" in code
        assert not any("node_modules" in cid for cid in code)

        # cosine sanity
        assert abs(pm.cosine([1, 0], [1, 0]) - 1) < 1e-9
        assert abs(pm.cosine([1, 0], [0, 1])) < 1e-9

        # live search against local TEI servers, if they're up
        try:
            pm.embed(["ping"])
        except OSError:
            print("skipped live search (8081/8082 not reachable)")
        else:
            texts = dict(pm.chunks())
            index = pm.build_index(texts)
            assert set(index) == set(texts)
            # cache hit: second build re-embeds nothing (would raise if it called a dead URL)
            old = pm.EMBED_URL
            pm.EMBED_URL = "http://192.0.2.1:1"
            assert set(pm.build_index(texts)) == set(texts)
            pm.EMBED_URL = old
            qvec = pm.embed(["where is the database code"])[0]
            best = max(index, key=lambda cid: pm.cosine(qvec, index[cid]))
            assert "arch.md" in best, best
            # code chunks are searchable too
            texts.update(pm.code_chunks())
            index = pm.build_index(texts)
            qvec = pm.embed(["invoice tax calculation"])[0]
            best = max(index, key=lambda cid: pm.cosine(qvec, index[cid]))
            assert best.startswith("src/billing.py"), best

    print("all checks passed")


if __name__ == "__main__":
    main()