Commit graph

16 commits

Author SHA1 Message Date
d3a3bccfbb feat(api): expose the §5 provenance stamp on IngestResult
The stamp ({stem}@{sha256(raw)[:16]}) was computed internally but only
written into frontmatter, forcing consumers to recompute it from the
manifest bytes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 03:46:52 +02:00
9ec25d27d0 feat(typing): ship the PEP 561 py.typed marker
Consumers run mypy --strict against the inline annotations; without the
marker every imported symbol degrades to Any.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 03:46:51 +02:00
dae0bd1a28 docs(readme): update status — phase 1 implemented 2026-07-16 20:14:35 +02:00
9b60f2c7b6 feat(api): export the Door A public surface; complete the §11 seam table
TDD step 9: package-root exports (materialize_bundle, IngestResult, the
typed error hierarchy, manifest types) and the two missing named seam
tests — provenance stamping verified with an independent frontmatter
parser, and navigability verified by resolving every index link. The
test module header maps all six library-side §11 seams to their named
tests; spec integrity stays with commons.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QeqhJpYQyghASjiJo5EhGg
2026-07-16 20:11:39 +02:00
9dd86b1b18 feat(examples): ship the §11 golden fixtures with byte-exact conformance
TDD step 8: three golden cases per the §11 format (manifest.json,
fixture/, ingested-at.txt, expected-bundle/) — ingest-golden-file and
ingest-golden-sql are the conformance MUSTs; ingest-golden-http
documents and exercises the optional extension against mock payloads.
The conformance test re-materializes each case into a fresh directory
and compares byte for byte; offline and credential-free (the sql
fixture is a committed database file, http never opens a socket).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QeqhJpYQyghASjiJo5EhGg
2026-07-16 20:09:03 +02:00
ab1fa4d999 feat(connectors): add the http connector and wire the network gate
TDD step 7: read_http executes the optional http extension point behind
an injectable transport seam (urllib_get is the only socket path; the
suite runs socket-free against a mock). credential_ref resolves from the
environment at run time, fail-fast before any transport call; the secret
rides in the Authorization header only. Explicit single-slash URL join,
CRLF-to-LF normalization, LF line-count cap (missing trailing newline
still counts), and code-fence-marker rejection. materialize_bundle
renders the body as a verbatim fenced block; the §8 gate test asserts
zero transport calls without the opt-in.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QeqhJpYQyghASjiJo5EhGg
2026-07-16 20:06:21 +02:00
f12fdc1dd0 feat(index): maintain existing indexes on re-materialization (spec §6)
TDD step 6: on an existing index, managed lines whose target is an
ingest-owned file removed this run are dropped, a managed label is
refreshed in place when the extraction title changes, and every other
line — curated links, promoted-verdict links, foreign line endings — is
preserved byte for byte. Load-bearing test: a promoted verdict and its
index link survive re-ingest unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QeqhJpYQyghASjiJo5EhGg
2026-07-16 20:04:21 +02:00
0ff946696c feat(materialize): add §5 materialization with collision gate and replacement
TDD step 5: materialize_bundle takes three explicit inputs (manifest,
bundle dir, regex-validated ingested_at — no wall-clock default) and
stages every extraction in memory before the first disk mutation. The
§3 collision gate refuses to overwrite any file without the ingest
stamp, before any mutation; replacement removes exactly the stamped
set. Frontmatter is the seven §5 keys in spec order with whitespace
collapse; output is LF-only raw bytes with one trailing newline; the
provenance stamp hashes the same bytes that are parsed. Fresh index.md
gets bundle_summary plus idempotent links in extraction order (§6
creation path; preserve/removal rules come next). The §8 network gate
refuses http fail-fast without the per-run opt-in; the http transport
itself lands in step 7.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QeqhJpYQyghASjiJo5EhGg
2026-07-16 20:02:35 +02:00
c94ed6d525 feat(connectors): add the sql connector (read-only sqlite, env-resolved)
TDD step 4: read_sql executes one read-only SELECT against the sqlite
database whose path is resolved at run time from the env var named by
connection_ref (credentials never in the manifest). Read-only enforced
by the connection mode (file:...?mode=ro), single statement via
Connection.execute, §5 cell text conversion, streaming max_rows cap,
and every sqlite failure wrapped in SourceError.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QeqhJpYQyghASjiJo5EhGg
2026-07-16 19:56:41 +02:00
af1849f0b3 feat(connectors): add the file connector with fail-closed path boundary
TDD step 3: read_csv executes a file-source extraction — boundary-checked
path resolution via commonpath on canonical paths (rejects .. traversal,
absolute paths, symlink escapes, and prefix-collision siblings), utf-8-sig
decoding, streaming max_rows cap as a typed error (never silent
truncation), ragged-row rejection, and verbatim cells (escaping stays in
the §5 renderers). New SourceError in the typed hierarchy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QeqhJpYQyghASjiJo5EhGg
2026-07-16 19:55:08 +02:00
cda4a6a497 feat(render): add §5 body renderers as pure functions
TDD step 2: markdown-table rendering with the load-bearing escape order
(backslash, then pipe, then newlines to spaces with CRLF as one unit),
SQL value-to-text conversion (NULL empty, plain-decimal integers,
shortest round-trip floats, explicit bool/BLOB rejection — never silent
coercion), and the verbatim fenced block for http bodies. Table shape
and fenced-block form match the reference implementation byte for byte
ahead of the shared §11 golden fixtures.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QeqhJpYQyghASjiJo5EhGg
2026-07-16 19:52:21 +02:00
54ac494830 feat(manifest): add fail-fast manifest validation (spec §3–§4)
TDD step 1 of the phase 1 plan: typed error hierarchy rooted in
IngestError, manifest parsing with schema validation before any source
call — id grammar, polymorphic source types, extraction rules, verdict
reservation (okf_type and filename namespace), and the no-embedded-
credentials rule for base_url. Dev tooling (pytest/mypy/ruff) added as
a PEP 735 dependency group; runtime dependencies stay empty.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QeqhJpYQyghASjiJo5EhGg
2026-07-16 19:47:29 +02:00
ec2d632b4f docs(readme): refresh status and link the phase plans
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QeqhJpYQyghASjiJo5EhGg
2026-07-16 11:01:09 +02:00
b0ad2aedfb docs(plan): add detailed phase 1-4 implementation plans
Phase 1 (Door A): ingest-spec v1 implementation + §11 golden fixtures,
pinned to the current spec revision, with TDD order and byte-exact
verification criteria. Phase 2 (Doors B/C): guard-gated inbox and
external bundle import. Phase 3: configurable bundle contract via a
profile object, default profile locked to the golden suite. Phase 4:
zero-dep Node half, coordination-first with owner sign-offs.

Each plan carries explicit key assumptions with tests and a
verification section.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QeqhJpYQyghASjiJo5EhGg
2026-07-16 10:58:08 +02:00
e57afecf72 docs(scope): expand roadmap to cover all eight OKF surfaces
Operator decision: the initial v1 boundary (portfolio pair only) left
five of eight OKF surfaces uncovered. CLAUDE.md/README now define a
four-phase roadmap: door A, doors B/C, configurable bundle contract
(wiki strict-v1), and a zero-dep Node/ESM half for the second-brain
plugin world. Halves share contract and fixtures, never code. Security
stays with llm-ingestion-guard in both runtimes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QeqhJpYQyghASjiJo5EhGg
2026-07-16 10:32:58 +02:00
47df0aeb4b 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
2026-07-16 10:12:59 +02:00