feat: initial commit — repo scaffold and v1 scope
Scope settled 2026-07-16: implements portfolio-optimiser-commons ingest-spec (commons keeps spec authorship), Python 3.10+ stdlib-only core, security delegated to llm-ingestion-guard at persist gates. Doors: spec-based ingestion, bundle inbox (md/txt/csv/json/html core, binary formats behind [extract]), external bundle import. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QeqhJpYQyghASjiJo5EhGg
This commit is contained in:
commit
47df0aeb4b
7 changed files with 268 additions and 0 deletions
21
.gitignore
vendored
Normal file
21
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Python
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
.venv/
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
*.egg-info/
|
||||||
|
.pytest_cache/
|
||||||
|
.mypy_cache/
|
||||||
|
.ruff_cache/
|
||||||
|
.coverage
|
||||||
|
|
||||||
|
# Environment / local
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
*.local.md
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Local-only: public remote — never publish session state or internal briefs
|
||||||
|
/STATE.md
|
||||||
|
/docs/oppstartsprompt.md
|
||||||
3
CHANGELOG.md
Normal file
3
CHANGELOG.md
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
113
CLAUDE.md
Normal file
113
CLAUDE.md
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
# llm-ingestion-okf
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
Shared OKF (Open Knowledge Format) ingestion library. Three entry doors,
|
||||||
|
one boundary rule:
|
||||||
|
|
||||||
|
- **Door A — spec-based ingestion:** implements the normative
|
||||||
|
`ingest-spec.md` owned by `portfolio-optimiser-commons` (manifest →
|
||||||
|
`file`/`sql`/`http` connector → deterministic materialization of
|
||||||
|
`ingest-{id}.md` → index generation; zero model calls). This repo
|
||||||
|
IMPLEMENTS the spec; commons keeps authorship. Spec changes the library
|
||||||
|
needs go via commons, never edited locally. The library ships the §11
|
||||||
|
golden fixtures (byte-exact) that are missing today.
|
||||||
|
- **Door B — bundle inbox:** converts dropped files to OKF concepts. All
|
||||||
|
file-type→text extraction lives HERE (the guard is text-only). v1 core:
|
||||||
|
`md`, `txt`, `csv`, `json`, `html` (stdlib). `pdf`/`docx`/`xlsx` only via
|
||||||
|
the optional `[extract]` extra; without it those types are rejected
|
||||||
|
fail-fast.
|
||||||
|
- **Door C — external bundle import:** third-party OKF bundles are assessed
|
||||||
|
per concept via the guard's `okf.import_bundle`; only non-rejected concepts
|
||||||
|
are merged/materialized/indexed here.
|
||||||
|
|
||||||
|
**Boundary rule (non-negotiable, zero overlap):** `llm-ingestion-guard`
|
||||||
|
(pinned `>=0.2,<0.3`) answers "is this content safe to persist?" —
|
||||||
|
scan/sanitize/quarantine/fail-secure/provenance-stamp. This library is
|
||||||
|
plumbing: connect source → materialize deterministic OKF bundle → generate
|
||||||
|
index. Never reimplement security; call the guard at persist gates
|
||||||
|
(`prepare_input`/`screen_output`, `okf.import_bundle`). When in doubt which
|
||||||
|
side of the boundary something belongs on: ask the operator.
|
||||||
|
|
||||||
|
**Implementation baseline:** the stricter behaviors from
|
||||||
|
`portfolio-optimiser` (streaming row caps, utf-8-sig, in-memory staging with
|
||||||
|
pre-mutation collision gate, validated `ingested_at`, typed `IngestError`)
|
||||||
|
are the library baseline. First consumer: `portfolio-optimiser-claude`.
|
||||||
|
|
||||||
|
### Open crossroads: the Node second-brain world (decision deferred)
|
||||||
|
|
||||||
|
The OKF second-brain plugins (okr, linkedin-studio, ms-ai-architect, and the
|
||||||
|
marketplace catalog spec) are deliberately Node/ESM zero-dependency and
|
||||||
|
cannot consume a Python library directly. okr has documented it does not
|
||||||
|
want a Python bridge. v1 therefore aligns with the catalog's
|
||||||
|
`okf-second-brain/spec.md` as a *contract* only and ships no Node code.
|
||||||
|
Revisit when any of these become true:
|
||||||
|
|
||||||
|
1. A second Node consumer needs shared ingestion *code*, not just the
|
||||||
|
catalog conventions (`okf-check.mjs`/`okf-index.mjs`).
|
||||||
|
2. okr's doc-conversion layer (docx/pdf/eml/html → md) gets built and
|
||||||
|
duplicates Door B's extraction logic.
|
||||||
|
3. The catalog's convention-level alignment proves insufficient to keep
|
||||||
|
bundle forms interoperable.
|
||||||
|
|
||||||
|
### Non-goals (v1)
|
||||||
|
|
||||||
|
- `strict-v1` wiki bundle profile (`claude-code-llm-wiki`) — v2 candidate;
|
||||||
|
requires a configurable bundle contract (types/layers/frontmatter sets/
|
||||||
|
reserved-file policy as config, not constants).
|
||||||
|
- Verdict/feedback machinery (method-spec) — stays in consumer repos.
|
||||||
|
- Embedding/RAG/retrieval layers.
|
||||||
|
|
||||||
|
## Stack
|
||||||
|
|
||||||
|
Python 3.10+. Package `llm_ingestion_okf` (src layout, hatchling).
|
||||||
|
**Zero runtime dependencies in the core** (stdlib only, like the guard).
|
||||||
|
The only permitted future runtime dependency is `llm-ingestion-guard`
|
||||||
|
(itself zero-dep), added when the first persist gate is implemented.
|
||||||
|
Binary extraction parsers live behind the `[extract]` extra only.
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
- Type hints everywhere; `mypy --strict` target.
|
||||||
|
- Determinism is bit-exact: `ingested_at` is an explicit required argument
|
||||||
|
(no wall-clock defaults); LF-only output; golden fixtures compared
|
||||||
|
byte-for-byte.
|
||||||
|
- No model calls anywhere in the run path.
|
||||||
|
- Credentials only as env-var *references* resolved at runtime; never in
|
||||||
|
manifests, logs, or frontmatter.
|
||||||
|
- Network access requires an explicit per-run opt-in flag; refuse fail-fast
|
||||||
|
otherwise.
|
||||||
|
- Conventional Commits: `type(scope): description`.
|
||||||
|
- English for all code, docs, and commit messages (public repo).
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
- Test: `pytest`
|
||||||
|
- Lint: `ruff check .` + `ruff format --check .`
|
||||||
|
- Type check: `mypy --strict src/`
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
- TDD: no production code without a failing test first.
|
||||||
|
- This repo is published PUBLICLY (`open/` namespace on Forgejo). `STATE.md`
|
||||||
|
and `docs/oppstartsprompt.md` are LOCAL-ONLY (gitignored) — never commit
|
||||||
|
session state or internal briefs. No secrets, sober English prose, no
|
||||||
|
marketing language.
|
||||||
|
- After `git commit`: push to Forgejo (`git push origin`) immediately.
|
||||||
|
Never GitHub.
|
||||||
|
|
||||||
|
## Communication patterns
|
||||||
|
|
||||||
|
### Linking to local files
|
||||||
|
|
||||||
|
When pointing to local files in responses, always use markdown link syntax
|
||||||
|
with a descriptive name:
|
||||||
|
|
||||||
|
- Use `[Human-friendly name](file:///absolute/path)` — never bare
|
||||||
|
`file:///...` URLs or autolinks `<file://...>`.
|
||||||
|
- Always use absolute paths. Never `~/` or relative paths.
|
||||||
|
- For multiple files, render as a bullet list of named markdown links.
|
||||||
|
|
||||||
|
Why: bare `file://` URLs only render the first as clickable across multiple
|
||||||
|
lines. Named markdown links make each entry independently clickable and look
|
||||||
|
cleaner.
|
||||||
21
LICENSE
Normal file
21
LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 Kjell Tore Guttormsen
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
60
README.md
Normal file
60
README.md
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
# llm-ingestion-okf
|
||||||
|
|
||||||
|
Shared ingestion library for OKF (Open Knowledge Format) bundles.
|
||||||
|
|
||||||
|
Status: pre-implementation. This repository currently contains the project
|
||||||
|
scaffold and scope definition only; no pipeline code has been written yet.
|
||||||
|
|
||||||
|
## Planned scope (v1)
|
||||||
|
|
||||||
|
The library provides three entry points for getting content into an OKF
|
||||||
|
bundle:
|
||||||
|
|
||||||
|
1. **Spec-based ingestion.** An implementation of the normative ingest
|
||||||
|
specification owned by `portfolio-optimiser-commons`: manifest →
|
||||||
|
`file`/`sql`/`http` connector → deterministic materialization of
|
||||||
|
`ingest-{id}.md` concept files → index generation. Zero model calls in the
|
||||||
|
run path; output is reproducible byte-for-byte against golden fixtures.
|
||||||
|
2. **Bundle inbox.** A drop directory where common file types are converted
|
||||||
|
to OKF concept files. All file-type→text extraction lives in this library:
|
||||||
|
`md`, `txt`, `csv`, `json`, and `html` are handled by the stdlib core;
|
||||||
|
`pdf`, `docx`, and `xlsx` require the optional `[extract]` extra and are
|
||||||
|
rejected fail-fast without it. Extracted text passes the security gate
|
||||||
|
before anything is persisted.
|
||||||
|
3. **External bundle import.** Import and merge of third-party OKF bundles:
|
||||||
|
each concept is assessed via the security gate, and only concepts that
|
||||||
|
pass are merged, materialized, and linked into the index.
|
||||||
|
|
||||||
|
## Boundary: security is delegated
|
||||||
|
|
||||||
|
Security is owned by the sibling package
|
||||||
|
[`llm-ingestion-guard`](https://git.fromaitochitta.com/open/llm-ingestion-pipeline-security)
|
||||||
|
(pinned `>=0.2,<0.3`). The division is strict:
|
||||||
|
|
||||||
|
- **guard** answers "is this content safe to persist?" — scan, sanitize,
|
||||||
|
quarantine, fail-secure, provenance stamping.
|
||||||
|
- **this library** does the plumbing — connect a source, materialize a
|
||||||
|
deterministic OKF bundle, generate the index — and calls the guard at every
|
||||||
|
persist gate (`prepare_input`/`screen_output` for extracted text,
|
||||||
|
`okf.import_bundle` for received bundles).
|
||||||
|
|
||||||
|
No security functionality is reimplemented here.
|
||||||
|
|
||||||
|
## Non-goals (v1)
|
||||||
|
|
||||||
|
- The `strict-v1` bundle profile used by `claude-code-llm-wiki` (candidate
|
||||||
|
for v2; requires a configurable bundle contract).
|
||||||
|
- A Node/JavaScript port for the OKF second-brain plugin ecosystem, which is
|
||||||
|
deliberately Node/ESM zero-dependency. See CLAUDE.md for the recorded
|
||||||
|
decision criteria.
|
||||||
|
- Verdict/feedback machinery from the method specification (stays in the
|
||||||
|
consuming repositories).
|
||||||
|
- Embedding- or retrieval-layer functionality.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
Python 3.10+. The core has zero runtime dependencies.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT — see [LICENSE](LICENSE).
|
||||||
38
pyproject.toml
Normal file
38
pyproject.toml
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
[build-system]
|
||||||
|
requires = ["hatchling"]
|
||||||
|
build-backend = "hatchling.build"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "llm-ingestion-okf"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Shared OKF (Open Knowledge Format) ingestion library: spec-based connectors, bundle inbox, and external-bundle import, with security delegated to llm-ingestion-guard."
|
||||||
|
readme = "README.md"
|
||||||
|
license = "MIT"
|
||||||
|
requires-python = ">=3.10"
|
||||||
|
authors = [{ name = "Kjell Tore Guttormsen" }]
|
||||||
|
classifiers = [
|
||||||
|
"Development Status :: 2 - Pre-Alpha",
|
||||||
|
"Intended Audience :: Developers",
|
||||||
|
"Operating System :: OS Independent",
|
||||||
|
"Programming Language :: Python :: 3",
|
||||||
|
"Programming Language :: Python :: 3.10",
|
||||||
|
]
|
||||||
|
# Core stays stdlib-only. The single permitted future runtime dependency is
|
||||||
|
# llm-ingestion-guard (>=0.2,<0.3), added when the first persist gate lands.
|
||||||
|
dependencies = []
|
||||||
|
|
||||||
|
[project.optional-dependencies]
|
||||||
|
# Reserved for binary file-type extraction parsers (pdf/docx/xlsx).
|
||||||
|
# Populated when Door B's binary extraction is implemented.
|
||||||
|
extract = []
|
||||||
|
|
||||||
|
[tool.hatch.build.targets.wheel]
|
||||||
|
packages = ["src/llm_ingestion_okf"]
|
||||||
|
|
||||||
|
[tool.ruff]
|
||||||
|
line-length = 100
|
||||||
|
target-version = "py310"
|
||||||
|
|
||||||
|
[tool.mypy]
|
||||||
|
strict = true
|
||||||
|
python_version = "3.10"
|
||||||
12
src/llm_ingestion_okf/__init__.py
Normal file
12
src/llm_ingestion_okf/__init__.py
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
"""Shared OKF (Open Knowledge Format) ingestion library.
|
||||||
|
|
||||||
|
Three entry doors: spec-based ingestion (manifest -> connector ->
|
||||||
|
deterministic materialization -> index), a bundle inbox converting common
|
||||||
|
file types to OKF concepts, and import of external OKF bundles. Security is
|
||||||
|
delegated to llm-ingestion-guard at every persist gate.
|
||||||
|
|
||||||
|
Pre-implementation: no pipeline code yet. See README.md and CLAUDE.md for
|
||||||
|
scope and boundaries.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__version__ = "0.1.0"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue