Pod

Yes, this is on purpose. Pod is built for agents, so the default page is plain HTML.
Human? View the normal website.
Agent? You probably prefer /mcp/akb/issues.md or /mcp/akb/issues.json, or Pod over MCP.

Reported issues for akb

Pod holds 13 of 13 problems reported by people outside the maintainer team. Issues filed by the project's own owners, members and collaborators are excluded entirely — a maintainer's release checklist is not a warning to a prospective user.

Back to akb.

Most discussed

Extend AKB table DDL tools with declarative unique keys, indexes, and check constraints

Background

AKB currently keeps schema changes behind dedicated DDL tools:

This boundary should remain. akb_sql should stay DML/query-oriented and should not become an arbitrary DDL execution surface.

However, the current DDL tools only expose basic column operations. They do not allow callers to define common database-level invariants such as uniqueness, lookup indexes, or simple check constraints. This makes clients implement

Read the thread · 2026-06-16 · closed · 2 comments

Extend AKB table DDL tools with declarative check_constraints (#215 follow-up, PR 2 of 2)

Summary

Follow-up to #215. The declarative unique_keys + indexes half shipped in #220 (PR 1 of 2). This issue tracks the remaining check_constraints (PR 2 of 2) — split out deliberately because it is the raw-SQL-injection-heaviest surface and warrants its own focused review.

Scope (from #215)

Add declarative check_constraints to akb_create_table (create-time) and akb_alter_table (add_check_constraints / drop_check_constraints). Declarative rule DSL — NOT raw SQL.

Read the thread · 2026-06-17 · closed · 1 comment

akb_search에서 특정 리소스 URI 목록으로 검색 범위 제한 지원

요약

akb_search에서 특정 AKB 리소스 URI 목록으로 검색 범위를 제한할 수 있으면 좋겠습니다.

현재는 vault, collection, type, tags, include_archived 기준으로만 검색 범위를 좁힐 수 있고, 이미 알고 있는 특정 문서/리소스 집합 안에서만 하이브리드 검색을 수행하는 방법이 없습니다.

현재 동작

akb_search는 검색 결과로 canonical akb://... URI를 반환하지만, 검색 입력에서는 URI 목록을 검색 범위로 받을 수 없습니다.

따라서 특정 리소스 집합 안에서만 검색하려면 각 URI를 개별적으로 읽은 뒤 호출하는 쪽에서 직접 처리해야 합니다. 이 방식은 AKB의 chunk-level retrieval, BM25/dense fusion, ranking, score를 활용하지 못합니다.

원하는 동작

akb_search가 선택적으로 URI 기반 검색 범위 필터를 받

Read the thread · 2026-06-08 · closed · external user · 1 comment

Backend image does not install application package for isolated CLI use

The backend Dockerfile installs the project before copying the declared Hatch packages into the image layer:

  1. COPY pyproject.toml .
  2. RUN pip install --no-cache-dir .
  3. COPY . .

This installs dependencies and distribution metadata, but the application packages are absent when the wheel is built. The resulting image works for the default server command only because WORKDIR is /app and the later source copy is importable from the current directory. An isolated invocation such as `p

Read the thread · 2026-08-26 · closed · 0 comments

grep replace rewrites documents outside the requested collection (unanchored, unescaped LIKE)

Summary

grep(replace=…) rewrites documents the caller never scoped. The collection filter is compiled as an unanchored, unescaped LIKE, so a rewrite scoped to one collection also rewrites every sibling collection whose path shares that prefix — each with its own git commit and re-index.

This fires on ordinary values, not adversarial ones: collection='core' also matches core-extra/….

Where

backend/app/services/search_service.py:1170 (and the sibling at :461):

d.pat

[Read the thread](https://github.com/dnotitia/akb/issues/338) · 2026-08-07 · open · 0 comments

### akb_grep(replace=…) rewrites only the first `limit` matching documents, contradicting the documented "every matching document" behaviour

## Summary

A find-and-replace across a scope with more matches than `limit` silently rewrites only the first `limit` documents and commits them, while the tool schema and help promise it rewrites *every* matching document. `limit` is documented as an output-only knob and is hard-capped at 50.

## Where

`SearchService.grep` computes `matched_docs` (all matches) then slices `result_docs = matched_docs[:limit]` (`backend/app/services/search_service.py:995-998`); the replace loop iterates only `re

[Read the thread](https://github.com/dnotitia/akb/issues/315) · 2026-07-28 · closed · 0 comments

### bug(mcp): access-gated tools return ForbiddenError as code=internal instead of permission_denied

## Summary

A non-admin (or otherwise unauthorized) caller hitting any **access-gated MCP tool** is correctly *rejected*, but the failure is surfaced under the generic **`code=internal`** envelope instead of a stable permission code (e.g. `permission_denied` / HTTP 403). Clients can't reliably distinguish "you lack the role" (a 4xx the caller should handle) from "the server crashed" (a 5xx).

## Impact

- Misleading error taxonomy for every admin/writer-gated MCP tool: `akb_alter_table`, `akb_dr

[Read the thread](https://github.com/dnotitia/akb/issues/221) · 2026-06-17 · closed · 0 comments

### Add a file replace/update API with an optimistic-concurrency precondition (expected hash/version)

## Current

File tools are create / read / delete only: `akb_put_file`, `akb_get_file`, `akb_delete_file`. There is no file update/replace operation, and no optimistic-concurrency precondition for files.

Documents already have both: `akb_update` accepts `expected_content_hash` and `expected_commit` and rejects with 409 when the current state has moved.

So files are the missing half of the symmetric document/file contract — a consumer can protect a document against out-of-band edits, but cannot

[Read the thread](https://github.com/dnotitia/akb/issues/177) · 2026-06-09 · closed · 0 comments

## Most recent

### akb_put: support an optional slug to set the document path/uri filename over MCP

## Current

`akb_put` (MCP) derives the document path filename from the title: `file_path = {collection}/{slugify(title)}.md`. An MCP caller cannot set the path filename independently of the title — passing `slug` is rejected outright:

    {"error": "Unknown argument 'slug' for akb_put", "code": "unknown_argument"}

The capability already exists below the MCP layer. `DocumentPutRequest` (`backend/app/models/document.py`) has a `slug` field, and `document_service` honors it:

    slug = (req.slu

[Read the thread](https://github.com/dnotitia/akb/issues/176) · 2026-06-09 · closed · 0 comments

### akb_browse: vault-root response emits an empty-name collection marker

## Observed

\`akb_browse(vault="kisa-poc-2")\` returns, as its first item:

\`\`\`json
{ "type": "collection", "name": "", "path": "", "uri": null }
\`\`\`

It's not a real collection — \`path\` and \`name\` are both empty, \`uri\` is null, clicking it leads nowhere meaningful.

## Why it matters

Every browse-rendering client has to special-case this row out of the response, otherwise it renders as an empty folder at the top of the vault listing (which is what was happening in our AKB Browser 

[Read the thread](https://github.com/dnotitia/akb/issues/82) · 2026-05-26 · closed · 0 comments

### akb_browse: vault-root response hides root-level documents (and depth=2 over-broadens)

## Observed (verified live on \`kisa-poc-2\`)

\`akb_browse(vault="kisa-poc-2")\` — i.e. the default \`depth=1\`:

| | total | types |
|---|---|---|
| default | 46 | collection: 5, file: 41 |
| \`depth=2\` | **88** | collection: 5, **document: 42**, file: 41 |
| \`content_type="documents"\` | 5 | collection-only (collections that *contain* documents — not the documents themselves) |

The vault holds 8 items at its root (5 collections + 3 root-level \`*.md\` documents) and 43 inside sub-collectio

[Read the thread](https://github.com/dnotitia/akb/issues/81) · 2026-05-26 · closed · 0 comments

### search_service.search lacks the same defense-in-depth user_id guard as .grep

## Summary

`SearchService.grep()` raises \`ValidationError(\"vault or user_id required\")\` when both \`vault\` and \`user_id\` are None (search_service.py:520), so a caller that forgets to forward \`user_id\` fails closed. **`SearchService.search()` has no equivalent guard.**

PR #67 (which closed #66) makes the MCP path always forward \`user_id\` from the handler, so the leak is gone today. But the service-layer is now fragile to the **next** caller — a new REST endpoint, an internal worker, 

[Read the thread](https://github.com/dnotitia/akb/issues/70) · 2026-05-21 · closed · 0 comments

### MCP akb_search omits user_id / vault read check, risking unauthorized search results

## Summary
The MCP `akb_search` handler currently calls `SearchService.search()` without passing the authenticated `uid`, and it also does not perform a vault-level read check when a `vault` argument is supplied.

## Evidence
In `backend/mcp_server/server.py`:

```py
@_h("akb_search")
async def _handle_search(args: dict, uid: str, user: _MCPUser) -> dict:
    result = await search_service.search(
        query=args["query"],
        vault=args.get("vault"),
        collection=args.get("collectio

[Read the thread](https://github.com/dnotitia/akb/issues/66) · 2026-05-21 · closed · outside contributor · 0 comments

The remaining reports are on [the project's issue tracker](https://github.com/dnotitia/akb/issues).