watchdog-intel 0.1.0a1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. watchdog_intel-0.1.0a1/.github/workflows/ci.yml +27 -0
  2. watchdog_intel-0.1.0a1/.github/workflows/claude-review.yml +39 -0
  3. watchdog_intel-0.1.0a1/.github/workflows/publish.yml +57 -0
  4. watchdog_intel-0.1.0a1/.gitignore +10 -0
  5. watchdog_intel-0.1.0a1/CLAUDE.md +104 -0
  6. watchdog_intel-0.1.0a1/INSTALL.md +298 -0
  7. watchdog_intel-0.1.0a1/LICENSE +21 -0
  8. watchdog_intel-0.1.0a1/PKG-INFO +458 -0
  9. watchdog_intel-0.1.0a1/README.md +404 -0
  10. watchdog_intel-0.1.0a1/pyproject.toml +53 -0
  11. watchdog_intel-0.1.0a1/src/watchdog/__init__.py +1 -0
  12. watchdog_intel-0.1.0a1/src/watchdog/cli.py +926 -0
  13. watchdog_intel-0.1.0a1/src/watchdog/pipeline/__init__.py +0 -0
  14. watchdog_intel-0.1.0a1/src/watchdog/pipeline/arrows_parser.py +121 -0
  15. watchdog_intel-0.1.0a1/src/watchdog/pipeline/batch_get.py +68 -0
  16. watchdog_intel-0.1.0a1/src/watchdog/pipeline/embed.py +134 -0
  17. watchdog_intel-0.1.0a1/src/watchdog/pipeline/near_dup.py +155 -0
  18. watchdog_intel-0.1.0a1/src/watchdog/pipeline/preprocess.py +503 -0
  19. watchdog_intel-0.1.0a1/src/watchdog/pipeline/preprocess_batch.py +151 -0
  20. watchdog_intel-0.1.0a1/src/watchdog/pipeline/write_entity.py +115 -0
  21. watchdog_intel-0.1.0a1/src/watchdog/pipeline/write_vault.py +715 -0
  22. watchdog_intel-0.1.0a1/src/watchdog/setup_cmd.py +294 -0
  23. watchdog_intel-0.1.0a1/src/watchdog/skills/records/_template.md +94 -0
  24. watchdog_intel-0.1.0a1/src/watchdog/skills/records/academic-research.md +127 -0
  25. watchdog_intel-0.1.0a1/src/watchdog/skills/records/administrative-tribunals.md +139 -0
  26. watchdog_intel-0.1.0a1/src/watchdog/skills/records/aircraft-logs.md +138 -0
  27. watchdog_intel-0.1.0a1/src/watchdog/skills/records/audio-video.md +138 -0
  28. watchdog_intel-0.1.0a1/src/watchdog/skills/records/audit-reports.md +125 -0
  29. watchdog_intel-0.1.0a1/src/watchdog/skills/records/bankruptcy.md +131 -0
  30. watchdog_intel-0.1.0a1/src/watchdog/skills/records/corporate-filings.md +158 -0
  31. watchdog_intel-0.1.0a1/src/watchdog/skills/records/corrections-records.md +145 -0
  32. watchdog_intel-0.1.0a1/src/watchdog/skills/records/court-documents.md +128 -0
  33. watchdog_intel-0.1.0a1/src/watchdog/skills/records/criminal-proceedings.md +147 -0
  34. watchdog_intel-0.1.0a1/src/watchdog/skills/records/dns-whois.md +131 -0
  35. watchdog_intel-0.1.0a1/src/watchdog/skills/records/election-filings.md +137 -0
  36. watchdog_intel-0.1.0a1/src/watchdog/skills/records/environmental-filings.md +133 -0
  37. watchdog_intel-0.1.0a1/src/watchdog/skills/records/financial-statements.md +141 -0
  38. watchdog_intel-0.1.0a1/src/watchdog/skills/records/foi-responses.md +125 -0
  39. watchdog_intel-0.1.0a1/src/watchdog/skills/records/government-contracts.md +140 -0
  40. watchdog_intel-0.1.0a1/src/watchdog/skills/records/government-reports.md +131 -0
  41. watchdog_intel-0.1.0a1/src/watchdog/skills/records/healthcare-licensing.md +125 -0
  42. watchdog_intel-0.1.0a1/src/watchdog/skills/records/immigration-refugee.md +132 -0
  43. watchdog_intel-0.1.0a1/src/watchdog/skills/records/insurance-filings.md +127 -0
  44. watchdog_intel-0.1.0a1/src/watchdog/skills/records/labour-arbitration.md +140 -0
  45. watchdog_intel-0.1.0a1/src/watchdog/skills/records/land-registries.md +163 -0
  46. watchdog_intel-0.1.0a1/src/watchdog/skills/records/legislation.md +128 -0
  47. watchdog_intel-0.1.0a1/src/watchdog/skills/records/legislature-transcripts.md +125 -0
  48. watchdog_intel-0.1.0a1/src/watchdog/skills/records/lobbying-records.md +145 -0
  49. watchdog_intel-0.1.0a1/src/watchdog/skills/records/municipal-records.md +135 -0
  50. watchdog_intel-0.1.0a1/src/watchdog/skills/records/news-clippings.md +129 -0
  51. watchdog_intel-0.1.0a1/src/watchdog/skills/records/police-records.md +141 -0
  52. watchdog_intel-0.1.0a1/src/watchdog/skills/records/procurement-records.md +134 -0
  53. watchdog_intel-0.1.0a1/src/watchdog/skills/records/professional-licensing.md +129 -0
  54. watchdog_intel-0.1.0a1/src/watchdog/skills/records/real-estate.md +130 -0
  55. watchdog_intel-0.1.0a1/src/watchdog/skills/records/regulatory-filings.md +146 -0
  56. watchdog_intel-0.1.0a1/src/watchdog/skills/records/tax-documents.md +142 -0
  57. watchdog_intel-0.1.0a1/src/watchdog/skills/records/vehicle-registrations.md +127 -0
  58. watchdog_intel-0.1.0a1/src/watchdog/skills/watchdog-context.md +165 -0
  59. watchdog_intel-0.1.0a1/src/watchdog/skills/watchdog-entity.md +104 -0
  60. watchdog_intel-0.1.0a1/src/watchdog/skills/watchdog-health.md +138 -0
  61. watchdog_intel-0.1.0a1/src/watchdog/skills/watchdog-ingest.md +598 -0
  62. watchdog_intel-0.1.0a1/src/watchdog/skills/watchdog-query.md +60 -0
  63. watchdog_intel-0.1.0a1/src/watchdog/skills/watchdog-surface.md +185 -0
  64. watchdog_intel-0.1.0a1/src/watchdog/skills/watchdog-wiki.md +132 -0
  65. watchdog_intel-0.1.0a1/tests/__init__.py +0 -0
  66. watchdog_intel-0.1.0a1/tests/conftest.py +13 -0
  67. watchdog_intel-0.1.0a1/tests/test_arrows_parser.py +95 -0
  68. watchdog_intel-0.1.0a1/tests/test_batch_get.py +155 -0
  69. watchdog_intel-0.1.0a1/tests/test_cli.py +743 -0
  70. watchdog_intel-0.1.0a1/tests/test_embed.py +209 -0
  71. watchdog_intel-0.1.0a1/tests/test_near_dup.py +166 -0
  72. watchdog_intel-0.1.0a1/tests/test_preprocess.py +205 -0
  73. watchdog_intel-0.1.0a1/tests/test_preprocess_batch.py +156 -0
  74. watchdog_intel-0.1.0a1/tests/test_write_entity.py +158 -0
  75. watchdog_intel-0.1.0a1/tests/test_write_vault.py +813 -0
@@ -0,0 +1,27 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - uses: actions/setup-python@v5
20
+ with:
21
+ python-version: ${{ matrix.python-version }}
22
+
23
+ - name: Install package and dev dependencies
24
+ run: pip install -e ".[dev]"
25
+
26
+ - name: Run tests
27
+ run: pytest
@@ -0,0 +1,39 @@
1
+ name: Claude Code Review
2
+
3
+ on:
4
+ pull_request:
5
+ types: [labeled]
6
+
7
+ jobs:
8
+ review:
9
+ if: github.event.label.name == 'claude-review' && github.actor == 'tomcardoso'
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ contents: read
13
+ pull-requests: write
14
+ id-token: write
15
+ actions: read
16
+ steps:
17
+ - name: Checkout repository
18
+ uses: actions/checkout@v4
19
+ with:
20
+ fetch-depth: 1
21
+
22
+ - name: Run Claude Code Review
23
+ uses: anthropics/claude-code-action@v1
24
+ with:
25
+ claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
26
+ label_trigger: claude-review
27
+ claude_args: |
28
+ --allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)"
29
+ prompt: |
30
+ REPO: ${{ github.repository }}
31
+ PR NUMBER: ${{ github.event.pull_request.number }}
32
+
33
+ Please review this pull request with a focus on:
34
+ - Code quality and best practices
35
+ - Potential bugs or issues
36
+ - Security implications
37
+ - Performance considerations
38
+
39
+ Provide detailed feedback using inline comments for specific issues.
@@ -0,0 +1,57 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ test:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+
13
+ - uses: actions/setup-python@v5
14
+ with:
15
+ python-version: "3.12"
16
+
17
+ - name: Install package and dev dependencies
18
+ run: pip install -e ".[dev]"
19
+
20
+ - name: Run tests
21
+ run: pytest
22
+
23
+ build:
24
+ needs: test
25
+ runs-on: ubuntu-latest
26
+ steps:
27
+ - uses: actions/checkout@v4
28
+
29
+ - uses: actions/setup-python@v5
30
+ with:
31
+ python-version: "3.12"
32
+
33
+ - name: Build sdist and wheel
34
+ run: |
35
+ pip install hatch twine
36
+ hatch build
37
+ twine check --strict dist/*
38
+
39
+ - uses: actions/upload-artifact@v4
40
+ with:
41
+ name: dist
42
+ path: dist/
43
+
44
+ publish:
45
+ needs: build
46
+ runs-on: ubuntu-latest
47
+ environment: pypi
48
+ permissions:
49
+ id-token: write # required for OIDC trusted-publisher auth
50
+
51
+ steps:
52
+ - uses: actions/download-artifact@v4
53
+ with:
54
+ name: dist
55
+ path: dist/
56
+
57
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,10 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.pyo
4
+ .DS_Store
5
+ .claude/
6
+ dev/batch_results.json
7
+ *.egg-info/
8
+ dist/
9
+ build/
10
+ .venv/
@@ -0,0 +1,104 @@
1
+ # Watchdog — developer notes
2
+
3
+ ## Testing
4
+
5
+ Write tests for new features and any non-trivial function. The suite lives in `tests/` and runs with:
6
+
7
+ ```
8
+ pipx run pytest
9
+ ```
10
+
11
+ Tests use `tmp_path` and `monkeypatch` to redirect `WATCHDOG_HOME`, `PROJECTS_FILE`, and `CONFIG_FILE` away from the real home directory — patch all three when testing anything that touches the registry or projects list. See the `wdg_home` and `configured` fixtures in `tests/test_cli.py` for the pattern.
12
+
13
+ CI runs on every push and PR via `.github/workflows/ci.yml`.
14
+
15
+ ---
16
+
17
+ ## Releasing to PyPI
18
+
19
+ The package publishes to PyPI automatically when a GitHub release is created. Publishing uses OIDC trusted-publisher auth — no API tokens or secrets.
20
+
21
+ **Release steps:**
22
+
23
+ 1. Bump `version` in `pyproject.toml` (follows [PEP 440](https://peps.python.org/pep-0440/): `0.1.0a1`, `0.1.0b1`, `0.1.0`, `0.2.0`, etc.)
24
+ 2. Commit and push
25
+ 3. On GitHub: Releases → Draft a new release → create a tag matching the version (e.g. `v0.1.0`) → Publish release
26
+ 4. The `.github/workflows/publish.yml` workflow fires, builds the sdist + wheel with `hatch`, and uploads to PyPI
27
+
28
+ The `pypi` GitHub environment and PyPI trusted-publisher entry for `watchdog-intel` are already configured — no further setup needed.
29
+
30
+ ---
31
+
32
+ ## Adding new record skills
33
+
34
+ ### Where skills live
35
+
36
+ Skill files live in `src/watchdog/skills/records/`. They are plain markdown. No code changes are needed — skills are automatically picked up by the setup process when a new file is added to that directory.
37
+
38
+ ### Standard structure
39
+
40
+ A blank template is at `src/watchdog/skills/records/_template.md` — copy it as the starting point for any new skill. Files starting with `_` are excluded from installation and will not be loaded by Claude.
41
+
42
+ Every skill file should follow this structure in order:
43
+
44
+ 1. **Intro paragraph** — one or two sentences explaining when this skill is loaded by `/ingest`. Name the document types that trigger it.
45
+ 2. **Document types covered** — a bulleted list of the specific document types the skill applies to. This is the one section where it is acceptable to list jurisdiction-specific document names (since those are the literal names of the documents). Group by jurisdiction if there are many.
46
+ 3. **Always-present fields table** — a two-column table (`Field` | `What to look for`) listing the fields that appear in virtually every document of this type. Extract these even when not prominently displayed.
47
+ 4. **Red flags section** — the most important section. Use sub-headings to group related red flags. Each red flag should be a bolded label followed by a sentence or two explaining what to look for and why it matters. Write for pattern recognition, not just field extraction.
48
+ 5. **Terminology table(s)** — one or more two-column tables (`Term` | `Meaning`) covering jargon a journalist would encounter. If the terminology varies significantly by jurisdiction, use a three-column table (`Term` | `Jurisdiction` | `Meaning`) or separate tables per jurisdiction.
49
+ 6. **Relationships to extract** — a numbered list of entity relationships the skill should produce (e.g. `Person → Company: Director`). Use the `→` notation.
50
+ 7. **What investigators typically miss** — a numbered list of six to eight specific things that experienced journalists often overlook when reading this document type. Be concrete and specific.
51
+ 8. **Sources and further reading** — three subsections: **Official and regulatory** (government agencies, regulators, FATF, OECD, accounting standards bodies), **Practitioner and public interest** (law firm guides, NGO reports, public interest organizations), and **Journalism resources** (publicly accessible tipsheets, press freedom organizations). Omit a subsection entirely if there is nothing worth citing. End with a **Notes on unsourced claims** paragraph for any red flag claims that could not be traced to a specific source — these are flagged for editorial review, not silently included as fact. Every claim in the red flags section should be traceable to at least one source in this section.
52
+
53
+ ### Authoring principles
54
+
55
+ - **Jurisdiction-agnostic by default.** Lead with principles and patterns that apply anywhere. Specific jurisdictions are examples, not the default frame. A journalist in Brazil or Germany should find the skill useful.
56
+ - **Jurisdiction-specific terminology tables are valuable** — but position them clearly as jurisdiction guides, not as the primary content. The always-present fields and red flags sections must be universal.
57
+ - **The red flags section is the most important.** This is where the skill earns its value. Think about what a twenty-year veteran investigative journalist would notice that a first-year reporter would miss.
58
+ - **Write for a smart investigative journalist, not a specialist.** Assume the reader knows how journalism works but may not know the specific document type deeply. Explain jargon; don't assume it.
59
+ - **Be specific.** "Look for unusual transactions" is useless. "A property transferred three or more times in 12 months may be involved in title fraud, mortgage fraud, or money laundering" is useful.
60
+
61
+ ### Before writing a new skill, ask the user
62
+
63
+ 1. What document type are you working with? (Get a sample if possible.)
64
+ 2. What jurisdiction(s) are most common for your work? (This shapes the terminology table.)
65
+ 3. Are there existing skills that overlap? (Check `src/watchdog/skills/records/` first — some document types are covered from a related angle by an existing skill.)
66
+
67
+ If the new skill would overlap significantly with an existing one, consider extending the existing skill rather than creating a new file.
68
+
69
+ ---
70
+
71
+ ## CLI style guide
72
+
73
+ All terminal output in `cli.py` follows a consistent visual language. The colour constants are defined at the top of the file — use them, never raw ANSI codes.
74
+
75
+ ### Colour semantics
76
+
77
+ | Constant | Use for |
78
+ |----------|---------|
79
+ | `_BOLD` | Project names, important counts, section headers |
80
+ | `_DIM` | Secondary metadata: dates, slugs, path labels, quiet prompts |
81
+ | `_CYAN` | Actionable items: file paths, commands the user should type, directory names like `_INCOMING/` |
82
+ | `_GREEN` | Success states (`Created:`) |
83
+ | `_YELLOW` | Warnings (pending files, things that need attention) |
84
+ | `_RESET` | Always close every coloured span |
85
+
86
+ ### Layout conventions
87
+
88
+ - **Indent everything 2 spaces** — all output lines start with `" "`. The banner and list headers set this pattern; every command should match it.
89
+ - **Bold name, dim slug** — when showing a project, display its human name in bold and its slug in dim on the same line: ` **My Project** [dim]my-project[/dim]`.
90
+ - **Cyan for paths, never dim** — file system paths and `watchdog …` commands the user should run are always `_CYAN`, not `_DIM`. Dim is for decorative/secondary text only.
91
+ - **Section headers: bold, no trailing colon** — e.g. ` **Documents by type**` not `Documents by type:`. The colon was dropped in the consistency pass.
92
+ - **Dim labels, normal counts** — in type-breakdown tables, the label is `_DIM`, the count is unstyled (so it reads at normal brightness).
93
+ - **No trailing colons on "Pending in" lines** — format is `Pending in _CYAN__INCOMING/_RESET <label>`.
94
+
95
+ ### Adding a new command
96
+
97
+ 1. Print a blank line before the first content line and after the last, matching the spacing in `cmd_status`.
98
+ 2. Use `_find_project` for any command that takes a project name — it handles prefix matching and exits cleanly.
99
+ 3. Never call `print(f"Error: …")` and continue — use `sys.exit(f"Error: …")`.
100
+ 4. If the command produces a success confirmation, use `_GREEN` for the label and `_BOLD` for the key value.
101
+
102
+ ### Adding a new CLI alias
103
+
104
+ Add the alias → canonical mapping to `_ALIASES` at the top of `cli.py`. Aliases are resolved before argparse sees `sys.argv`, so they are invisible to `--help`. Add a parametrized test case to the `test_aliases_remap_argv` test in `tests/test_cli.py`.
@@ -0,0 +1,298 @@
1
+ # Installing Watchdog
2
+
3
+ Watchdog is a tool for managing large collections of public records. Once installed, you drop documents into a folder and Watchdog extracts the names, addresses, companies, and connections — then lets you ask questions in plain language.
4
+
5
+ This guide assumes you have never used a terminal before. Read through it once before starting.
6
+
7
+ ---
8
+
9
+ ## What you need
10
+
11
+ | What | Why | Free? |
12
+ |------|-----|-------|
13
+ | A computer running macOS, Linux, or Windows | Watchdog runs on your computer, not in the cloud | n/a |
14
+ | [Obsidian](https://obsidian.md) | The app where you'll read and explore your documents | Free |
15
+ | [Claude Code](https://claude.ai/download) | The AI assistant that reads and connects your documents | Free to install |
16
+ | A Claude.ai Pro or Max subscription | Powers the AI — required for document processing | Pro ~$20/month; Max from $100/month |
17
+
18
+ **Obsidian** is a note-taking app that Watchdog uses to organize and display your research. You don't need to know how to use it before starting — Watchdog sets it up for you.
19
+
20
+ **Claude Code** is the AI assistant that does the document processing. It's made by Anthropic, the same company that makes Claude. You install it once on your computer.
21
+
22
+ **A subscription** is required because processing documents requires AI. A Pro subscription ($20/month) is enough for most journalism work. If you're ingesting hundreds of documents at a time, Max (from $100/month) gives you higher limits.
23
+
24
+ ---
25
+
26
+ ## Step 1: Install Obsidian
27
+
28
+ 1. Go to [obsidian.md](https://obsidian.md) and click **Download**
29
+ 2. Open the downloaded file and drag Obsidian to your Applications folder
30
+ 3. Open Obsidian — it will ask you to create or open a vault. Click **Create new vault** and give it any name for now (you'll create your real investigation vaults later)
31
+
32
+ ---
33
+
34
+ ## Step 2: Install Claude Code
35
+
36
+ 1. Go to [claude.ai/download](https://claude.ai/download) and download the app
37
+ 2. Open the downloaded file and follow the installation instructions
38
+ 3. Open Claude Code and sign in with your Claude.ai account
39
+
40
+ If you don't have a Claude.ai account yet, create one at [claude.ai](https://claude.ai) and subscribe to Pro or Max before continuing.
41
+
42
+ ---
43
+
44
+ ## Step 3: Open Terminal
45
+
46
+ Terminal is a built-in app that lets you type commands to your computer. You'll only need it for the next few steps.
47
+
48
+ **macOS:** Press **Command + Space**, type **Terminal**, press Return.
49
+
50
+ **Linux:** Press **Ctrl + Alt + T**, or search for Terminal in your application menu.
51
+
52
+ **Windows:** Press **Windows + R**, type **cmd**, press Return. Or install [Windows Terminal](https://apps.microsoft.com/detail/9n0dx20hk701) for a better experience.
53
+
54
+ ---
55
+
56
+ ## Step 4: Install prerequisites
57
+
58
+ Watchdog requires two tools for processing PDFs: **qpdf** and **ghostscript**. It also requires **pipx** to install Python tools.
59
+
60
+ **macOS:**
61
+ ```
62
+ brew install qpdf ghostscript pipx
63
+ pipx ensurepath
64
+ ```
65
+ Then close and reopen Terminal so the new `pipx` path takes effect.
66
+
67
+ If you don't have Homebrew, install it first: [brew.sh](https://brew.sh)
68
+
69
+ **Ubuntu / Debian Linux:**
70
+ ```
71
+ sudo apt install qpdf ghostscript pipx tesseract-ocr libtesseract-dev
72
+ ```
73
+
74
+ **Fedora / RHEL Linux:**
75
+ ```
76
+ sudo dnf install qpdf ghostscript pipx tesseract tesseract-devel
77
+ ```
78
+
79
+ **Windows:**
80
+ - qpdf: [github.com/qpdf/qpdf/releases](https://github.com/qpdf/qpdf/releases) — download the installer
81
+ - ghostscript: [ghostscript.com/releases/gsdnld.html](https://ghostscript.com/releases/gsdnld.html) — download the installer
82
+ - pipx: open Terminal and run `python -m pip install pipx`, then `pipx ensurepath`
83
+
84
+ ---
85
+
86
+ ## Step 5: Install Watchdog
87
+
88
+ ```
89
+ pipx install watchdog-intel
90
+ ```
91
+
92
+ Wait for it to finish. You'll see a message saying the installation is complete.
93
+
94
+ ---
95
+
96
+ ## Step 6: Run setup
97
+
98
+ ```
99
+ watchdog setup
100
+ ```
101
+
102
+ This will:
103
+ - Verify that qpdf and ghostscript are installed
104
+ - Install the Watchdog skills into Claude Code
105
+ - Ask where you want to store your investigation projects
106
+ - Set up tab completion in your shell
107
+
108
+ It will ask one question: where to store your projects. Press Return to accept the default, or type a different path.
109
+
110
+ When it finishes, reload your shell as instructed (e.g. `source ~/.zshrc`), then:
111
+
112
+ ```
113
+ watchdog new "My Investigation"
114
+ ```
115
+
116
+ ---
117
+
118
+ ## Creating your first investigation
119
+
120
+ When you're ready to start a new investigation, type:
121
+
122
+ ```
123
+ watchdog new "My Investigation Name"
124
+ ```
125
+
126
+ Use a descriptive name — it will become the name of your Obsidian vault. For example:
127
+ ```
128
+ watchdog new "Shell Company Investigation"
129
+ ```
130
+
131
+ Watchdog will create a folder in your projects directory and print instructions.
132
+
133
+ **To open the investigation in Obsidian:**
134
+ 1. Open Obsidian
135
+ 2. Click the vault icon in the bottom-left corner
136
+ 3. Click **Open folder as vault**
137
+ 4. Navigate to your investigation folder and click Open
138
+
139
+ **To open the investigation in Claude Code:**
140
+ 1. Open Claude Code
141
+ 2. Click **Open project** or use File → Open
142
+ 3. Navigate to your investigation folder and click Open
143
+
144
+ You're ready to start ingesting documents.
145
+
146
+ ---
147
+
148
+ ## How to ingest documents
149
+
150
+ **Drop files into the Incoming folder:**
151
+
152
+ In your file manager, navigate to your investigation folder. You'll see a folder called `_INCOMING`. Drag any documents you want to process into this folder.
153
+
154
+ Supported file types: PDF, Word documents, Excel spreadsheets, images (JPG, PNG, TIFF), web pages (HTML), and plain text files.
155
+
156
+ **Start a Claude Code session:**
157
+
158
+ With Claude Code open and your investigation folder as the project, simply open a session. Claude will automatically check the Incoming folder for files at the start of every session and process them before anything else.
159
+
160
+ You can also type `/watchdog-ingest` at any time to process files manually.
161
+
162
+ **Watch for the briefing:**
163
+
164
+ After processing, Claude will produce a briefing showing:
165
+ - What documents were processed
166
+ - What entities (people, companies, addresses) were found
167
+ - Connections between entities that were already in your vault
168
+ - Anything that looks unusual
169
+
170
+ ---
171
+
172
+ ## Asking questions
173
+
174
+ Once documents are ingested, you can ask questions in plain English:
175
+
176
+ - `/watchdog-query Who are the directors of Shell Co Ltd?`
177
+ - `/watchdog-query What address does John Doe use?`
178
+ - `/watchdog-query Which companies share the address 123 Main St?`
179
+
180
+ Claude will answer using only the documents in your vault and will cite the specific page it's drawing from.
181
+
182
+ ---
183
+
184
+ ## Finding connections
185
+
186
+ Type `/watchdog-surface` to run a full connection analysis across your entire vault. Claude will look for:
187
+
188
+ - Addresses shared by companies that have no other apparent connection
189
+ - People appearing in unusual roles
190
+ - Entities mentioned in many documents but with no documented relationships
191
+
192
+ ---
193
+
194
+ ## Checking vault health
195
+
196
+ Type `/watchdog-health` to check for any problems with your vault — missing files, broken links, or incomplete records.
197
+
198
+ ---
199
+
200
+ ## Tips
201
+
202
+ **Ingesting web pages directly from your browser:**
203
+ Install the [Obsidian Web Clipper](https://obsidian.md/clipper) browser extension. Point it at your investigation vault and set the destination folder to `_INCOMING`. You can then clip any web page — news articles, company profiles, government announcements — directly into the ingest pipeline with one click, without downloading anything manually.
204
+
205
+ **Naming your documents before ingesting:**
206
+ Watchdog uses the filename to organize documents. A filename like `shell-co-annual-report-2023.pdf` is much more useful than `scan0042.pdf`. Rename files before dropping them into Incoming when possible.
207
+
208
+ **Adding context with sidecar files:**
209
+ If you want to record where a document came from before Claude processes it, create a text file with the same name but `.yml` extension. For example, alongside `shell-co-annual-report-2023.pdf`, create `shell-co-annual-report-2023.yml` containing:
210
+
211
+ ```
212
+ source: https://www.sedar.com/filing/xyz
213
+ obtained: 2026-06-05
214
+ notes: Check the director change on page 12.
215
+ ```
216
+
217
+ This context is merged into the document record and preserved even if you re-ingest the document later.
218
+
219
+ **Multiple investigations:**
220
+ Each investigation is a separate vault. Create as many as you need:
221
+ ```
222
+ watchdog new "City Hall Investigation"
223
+ watchdog new "Contractor Investigation"
224
+ ```
225
+
226
+ To switch between investigations, switch the open folder in both Obsidian and Claude Code.
227
+
228
+ To list all your investigations:
229
+ ```
230
+ watchdog list
231
+ ```
232
+
233
+ To reopen an investigation in Claude Code:
234
+ ```
235
+ watchdog open shell-company-investigation
236
+ ```
237
+
238
+ ---
239
+
240
+ ## Troubleshooting
241
+
242
+ **`watchdog: command not found`**
243
+ The install didn't add `watchdog` to your path. Try:
244
+ ```
245
+ pipx ensurepath
246
+ ```
247
+ Then close and reopen your terminal, and try again.
248
+
249
+ **`Watchdog isn't set up yet`**
250
+ Run:
251
+ ```
252
+ watchdog setup
253
+ ```
254
+
255
+ **`qpdf not found` or `ghostscript not found` during setup**
256
+ Install the missing tool for your platform (see Step 4 above), then run `watchdog setup` again.
257
+
258
+ **A document lands in `_FAILED/`**
259
+ The document couldn't be processed. Common reasons:
260
+ - Password-protected PDF — remove the password and try again
261
+ - Corrupted file — try re-downloading the document
262
+ - Unsupported format — check the supported file types list above
263
+
264
+ To retry: move the file from `_INCOMING/_FAILED/` back to `_INCOMING/`, then run `/watchdog-ingest` in Claude Code.
265
+
266
+ **Rate limit errors during a large ingest**
267
+ If you're ingesting many documents at once and Claude hits a rate limit, it will stop and log where it paused. Files that were successfully processed will be in `morgue/`. Files that weren't processed will still be in `_INCOMING/`. Start a new Claude Code session and run `/watchdog-ingest` again — it will pick up where it left off, skipping any already-processed files.
268
+
269
+ ---
270
+
271
+ ## Audio and video transcription (optional)
272
+
273
+ Watchdog can transcribe audio and video files if you install support for it. This requires **ffmpeg** and adds roughly 2 GB of dependencies.
274
+
275
+ **macOS:** `brew install ffmpeg`
276
+ **Ubuntu/Debian:** `sudo apt install ffmpeg`
277
+ **Windows:** [ffmpeg.org/download.html](https://ffmpeg.org/download.html)
278
+
279
+ Then reinstall Watchdog with transcription support:
280
+ ```
281
+ pipx install watchdog-intel[asr] --force
282
+ ```
283
+
284
+ ---
285
+
286
+ ## Getting help
287
+
288
+ If something isn't working, the best place to get help is the Watchdog GitHub repository:
289
+
290
+ ```
291
+ https://github.com/tomcardoso/watchdog/issues
292
+ ```
293
+
294
+ When reporting a problem, include:
295
+ - What you typed or did
296
+ - What you expected to happen
297
+ - What actually happened (copy and paste any error messages)
298
+ - Your operating system and version
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Tom Cardoso
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.