Use the inbox
Drop a file, watch the daemon classify it into R&D triage, drive the queue.
The inbox watcher monitors one or more directories and automatically ingests new files into your knowledge base. It runs every two minutes as part of the embed daemon.
Default inbox directory
The single canonical drop zone is inbox/ at the project root (ADR-0045 §C):
inbox/
Drop any file there and it will be processed within two minutes.
Drop convention (atomic handoff). To avoid the watcher reading a half-written file, assemble it under inbox/.staging/ and then atomically rename it into inbox/. The watcher ignores dotfiles and inbox/.staging/, and skips any top-level file whose size is still changing — so a partial drop is never consumed.
inbox/ is the only drop zone. There is no .construct/inbox/ or docs/intake/ zone — drop everything into inbox/.
Add extra directories
Set CX_INBOX_DIRS to a colon-separated list of additional paths:
# In ~/.config/construct/config.env
CX_INBOX_DIRS=/Users/you/Downloads/construct-inbox:/Volumes/shared/team-docs
All directories are watched in addition to inbox/: you cannot disable the default.
Supported file types
The inbox watcher accepts any file that can produce extractable text:
- Plain text / Code:
.md,.txt,.rst,.adoc,.json,.yaml,.yml,.toml,.js,.mjs,.ts,.tsx,.jsx,.py,.go,.rs,.sh,.bash,.html,.css,.csv,.tsv,.xml,.env,.conf,.ini,.sql,.log - Transcripts:
.vtt(WebVTT),.srt(SubRip),.lrc(lyrics),.transcript: Zoom, Teams, meeting recordings - Office documents (via docling):
.docx,.xlsx,.pptx,.odt,.ods - Rich text (via docling):
.doc,.rtf - Legacy iWork/Office (via docling):
.xls,.ppt,.pages,.numbers,.key - PDF (via docling, layout-aware + built-in OCR):
.pdf - Audio / Video (via whisper.cpp,
brew install whisper-cpp):.mp3,.wav,.m4a,.mp4,.mov,.avi,.mkv,.flac,.ogg,.webm,.m4v
This includes things like meeting notes, exports, specs, ADR drafts, research notes, recordings, and uploaded documents, as long as the file type is extractable.
Extraction backends. The default adapter strategy extracts plain PDF and DOCX through Node-native optional dependencies (unpdf, mammoth), so everyday ingest needs no Python and no system extractor on PATH; when those deps are absent it degrades to the system extractors (pdftotext, textutil). High-fidelity extraction — layout-aware tables, built-in OCR for scanned PDFs, legacy Office — runs through a docling Python sidecar provisioned automatically via uv; select it per ingest with --with-docling (or the docling-remote strategy). Audio/video routes through whisper.
Binary files that cannot be read as text are skipped with a warning observation.
50 MB hard cap: files above this are skipped silently.
How routing works
Files are routed to a typed subdirectory of .construct/knowledge/ based on filename patterns:
| Filename pattern | Knowledge subdirectory |
|---|---|
adr-NNN-* | decisions/ |
*runbook*, *how-to* | how-tos/ |
*customer*, *feedback* | external/ |
*postmortem*, *incident* | internal/ |
| Everything else | internal/ (default) |
Avoid re-processing
The watcher tracks which files it has already seen by recording a content hash. Editing a file causes it to be re-ingested. Renaming a file also triggers re-ingestion.
Check what was ingested
construct knowledge index
Or use the dashboard Knowledge tab.
Docs lane promotion
When a file lands in inbox/, Construct ingests it into .construct/knowledge/ and observations as usual. If the repo already has a matching docs lane such as docs/notes/meetings/, templates/docs/prds/, or templates/docs/rfcs/, the watcher also writes a promoted markdown copy into that lane for review and incorporation.
R&D triage on every file
After ingestion, the daemon classifies each file via classifyRdIntake and writes a triage packet to .construct/intake/pending/<id>.json. Inspect and drive the queue with construct intake list / show / done / skip / reopen. For non-trivial signals, generate a task graph with construct graph from-intake <id>.
A full walkthrough of the triage taxonomy (intake types, R&D stages, recommended chains, recommended actions) lives in Concepts: Intake and triage. Session-start surfaces the most recent pending packets with a one-line triage summary per entry.