Skip to content

feat: add document format import (SDD/TDD, MCP integration, review hardening) - #8

Merged
superops-team merged 6 commits into
mainfrom
feat/document-format-import
Aug 29, 2026
Merged

feat: add document format import (SDD/TDD, MCP integration, review hardening)#8
superops-team merged 6 commits into
mainfrom
feat/document-format-import

Conversation

@superops-team

Copy link
Copy Markdown
Owner

Summary

Implements OKF v1.3 document format import (pdf / docx / xlsx / pptx / html / csv / txt), driven by openspec SDD/TDD — spec 29 scenarios S1–S29, 29/29 conformance (openspec/changes/add-document-format-import/conformance.md).

What's included

  • pkg/convert — pure-Go conversion layer on downmark v0.10.0 (Go-1.26 toolchain), with input-size (64MiB) / result-size (32MiB) limits, per-call timeout control, and deterministic staging output.
  • okf add — document files and archives (zip/tar/tar.gz/tar.bz2) are converted/extracted into a deterministic staging dir before smart import; dry-run supported; a single conversion failure never aborts the batch (S15); all-failed exits non-zero.
  • MCPokf_import_document tool (stdio already Content-Length framed from PR feat: add MCP server with stdio transport and project knowledge base #6), plus searchability verification across all 7 formats (S29).
  • Spec & norms — openspec proposal/design/spec/tasks/conformance + AGENTS.md (19-dimension development norm, SDD/TDD + wiring/coverage requirements).

Two-round code review fixes (included in this PR)

Round 1 (explicit): removed dead code (collectMarkdownFiles, computeTargetPath); tightened dry-run (no files at all) and mixed-report (captured stdout asserts Converted (documents): 1) test assertions; documented Options.Timeout == 0 semantics.

Round 2 (latent):

  • Archive hardening: whole-archive <= 50MB (okf.MaxArchiveSize), per-member <= 10MB, io.LimitedReader decompression guard against forged/absent size headers, explicit .tar.xz rejection with guidance; zip-slip/symlink rejected.
  • Single-document conversion failure now returns exit code 1 (was silently 0); partial failure keeps S15 batch semantics; summary reports Failed (documents).
  • Added tests: special-character title YAML round-trip, .tar.xz clear error, all-conversion-failed exit code.

Verification

  • go build ./... / go vet ./... clean
  • go test ./... all pass (56 tests, incl. golden fixtures + existing suite)
  • test_mcp.py E2E green (incl. okf_import_document)

Known limits (documented in conformance.md)

  • okf sync does not track converted-document sources (staging path is ephemeral); track changes via okf add <doc> — no data loss (DetectSourceMissing only flags, never deletes).
  • MCP okf_import_document writes <original>.md at bundle root and overwrites same-name files (no merge policy, per spec S22).

superops-bot added 6 commits August 29, 2026 08:56
…rdening)

Implements OKF v1.3 document format import driven by openspec SDD/TDD
(S1-S29, 29/29 conformance):

- pkg/convert: pure-Go conversion layer on downmark v0.10.0
  (pdf/docx/xlsx/pptx/html/csv/txt), with input/result limits, timeout
  control, deterministic staging output
- cmd okf add: document conversion + full archive extraction (zip/tar/
  tar.gz/tar.bz2) staged before smart import; dry-run supported;
  per-file failure never aborts the batch
- MCP: okf_import_document tool (Content-Length framed stdio already in
  PR #6)
- openspec: proposal/design/spec/tasks/conformance + 19-dim AGENTS.md
  development norm
- docs: v1.3.0 release notes, CLI/README updates

Two-round code review fixes included:
- Round 1 (explicit): removed dead code (collectMarkdownFiles,
  computeTargetPath); tightened dry-run & mixed-report test assertions;
  documented Timeout==0 semantics
- Round 2 (latent): archive hardening (whole-archive <=50MB, per-member
  <=10MB, io.LimitedReader decompression guard against forged headers,
  explicit .tar.xz error); single-document conversion failure now exits
  non-zero (all-failed) while partial failure keeps batch semantics;
  added special-title YAML round-trip, tar.xz, and all-conversion-failed
  tests; recorded known limits (okf sync does not track doc sources,
  MCP overwrite semantics) in conformance.md

Verified: go build/vet clean, all tests pass (56), test_mcp.py E2E green.
The project go.mod requires go 1.26 (downmark v0.10.0 toolchain);
Go 1.20 cannot parse `go 1.26.0` / `toolchain` directives, which broke
the build check on PR #8. Align the CI toolchain with go.mod.
- concurrency: KnowledgeBundle RWMutex (Add/RemoveConcept write, FilterConcepts/
  Stats/GetConcept read, delegated filters inherit read lock); fix shared mutable
  cfg in stress concurrent-generation test (per-goroutine copy)
- staticcheck: fix archive tempdir cleanup leak (defer bound to empty func),
  tar.TypeRegA deprecation, duplicated assertion in deps_test, drop 2 dead funcs
- coverage: whole-repo >=60% gate wired into CI and gauntlet
- property tests (testing/quick, zero new deps): equalFold vs strings.EqualFold,
  containsFold/indexFold consistency, sanitizeFilename safe+idempotent,
  WrapConcept frontmatter round-trip through parser
- gauntlet: tools/gauntlet.sh (build/vet/gofmt/staticcheck/test -race/coverage/
  shuffle/mutation/real-exec, fail-on-first) + tools/mutants.sh (4/4 killed)
- tests: cover extractTarFull branches (gzip/plain/symlink/size/traversal),
  WrapConcept direct unit test
- ci: run gauntlet as single gate, install staticcheck
- style: gofmt over tracked files (format-only)
- docs: AGENTS.md gains GAUNTLET/concurrency/property-test norms
- mark tools/*.sh executable in git (were 100644 -> 100755); CI checkout
  could not execute tools/mutants.sh, failing the gauntlet step with 126
- invoke mutants via `bash tools/mutants.sh` so it does not depend on the
  exec bit at runtime
- bump actions/checkout + actions/setup-go to v5 (drop Node.js 20 deprecation
  warning)
@superops-team
superops-team merged commit 56a3023 into main Aug 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant