depdesk 0.1.0__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.
depdesk-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Wendel Ortiz
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.
depdesk-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,316 @@
1
+ Metadata-Version: 2.4
2
+ Name: depdesk
3
+ Version: 0.1.0
4
+ Summary: Know which of your model calls are on a clock.
5
+ Author: Wendel Ortiz
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/Ort0x36/deprecation-desk
8
+ Project-URL: Source, https://github.com/Ort0x36/deprecation-desk
9
+ Project-URL: Issues, https://github.com/Ort0x36/deprecation-desk/issues
10
+ Project-URL: Changelog, https://github.com/Ort0x36/deprecation-desk/blob/main/CHANGELOG.md
11
+ Keywords: llm,llmops,deprecation,model-deprecation,model-lifecycle,openai,anthropic,claude,gpt,ai-engineering,static-analysis,linter,cli,ci,migration,technical-debt
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Software Development :: Quality Assurance
22
+ Classifier: Topic :: Software Development :: Build Tools
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.9
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Dynamic: license-file
28
+
29
+ # depdesk
30
+
31
+ **Know which of your model calls are on a clock.**
32
+
33
+ [![ci](https://github.com/Ort0x36/deprecation-desk/actions/workflows/ci.yml/badge.svg)](https://github.com/Ort0x36/deprecation-desk/actions/workflows/ci.yml)
34
+ [![pypi](https://img.shields.io/pypi/v/depdesk)](https://pypi.org/project/depdesk/)
35
+ [![python](https://img.shields.io/badge/python-3.9%20to%203.13-blue)](https://www.python.org/downloads/)
36
+ [![dependencies](https://img.shields.io/badge/dependencies-none-brightgreen)](pyproject.toml)
37
+ [![licence](https://img.shields.io/badge/licence-MIT-blue)](LICENSE)
38
+
39
+ Providers retire models on their schedule, not yours. The notice arrives by
40
+ email, to one person, months before anything breaks, and then it is forgotten
41
+ until a request starts failing in production. `depdesk` crosses the deprecation
42
+ notices you did not read with the models your code actually calls, and fails
43
+ your build while there is still time to do something about it.
44
+
45
+ Zero dependencies. Python 3.9 or newer. Anthropic and OpenAI today, and any
46
+ provider you write a catalog entry for.
47
+
48
+ ## Install
49
+
50
+ ```bash
51
+ pip install depdesk
52
+ ```
53
+
54
+ ## Try it in thirty seconds
55
+
56
+ ```bash
57
+ depdesk check .
58
+ ```
59
+
60
+ That is the whole setup. Point it at a repository and it reports every model
61
+ identifier it finds, crossed against the provider's published deprecation
62
+ dates. There is a deliberately broken sample in
63
+ [`examples/legacy-app`](examples/legacy-app) if you want to see a failing run
64
+ before pointing it at your own code.
65
+
66
+ ```
67
+ $ depdesk check . --fail-in 60
68
+ depdesk: 2 files scanned in .
69
+ catalog verified 2026-09-20 (2 days ago)
70
+
71
+ ALREADY RETIRED
72
+
73
+ claude-opus-4-1-20250805
74
+ provider: anthropic
75
+ retirement: 2026-08-05 (48 days ago)
76
+ announced: 2026-06-05
77
+ replacement: claude-opus-4-8
78
+ app/legacy.py:1: OLD = "claude-opus-4-1-20250805"
79
+
80
+ RETIRES SOON
81
+
82
+ gpt-5.4-cyber
83
+ provider: openai
84
+ retirement: 2026-10-01 (9 days left)
85
+ announced: 2026-09-11
86
+ replacement: gpt-5.6-cyber
87
+ app/legacy.py:2: CYBER = "gpt-5.4-cyber"
88
+
89
+ DEPRECATED PARAMETERS
90
+
91
+ temperature
92
+ behaviour: Returns a 400 error when set to a non-default value.
93
+ replacement: Omit the parameter and steer behaviour through prompting.
94
+ sdk: The Python SDK (v1.0 and later) removes temperature, top_p
95
+ and top_k, so passing them raises a TypeError.
96
+ app/legacy.py:9: temperature=0,
97
+ file also names: claude-opus-5
98
+
99
+ Summary: 1 already retired, 1 retires soon.
100
+ $ echo $?
101
+ 2
102
+ ```
103
+
104
+ Every line of that output is real: it is the tool running against a two file
105
+ sample, not a mockup.
106
+
107
+ ## What it finds
108
+
109
+ **Models on a clock.** Identifiers written anywhere in the tree, including
110
+ `.env` files and config, matched against the provider's own retirement dates.
111
+ Each finding carries the announcement date, the retirement date, the
112
+ replacement the provider names, and the exact lines where you use it.
113
+
114
+ **Deprecated parameters.** Model retirement is the loud failure. The quiet one
115
+ is a parameter that starts returning 400 on newer models while your code keeps
116
+ passing it, which is what happened to `temperature`, `top_p` and `top_k` on
117
+ Claude Opus 4.7 and later. No changelog files that under "deprecation", and
118
+ nothing in your test suite catches it if your tests never hit the new model.
119
+ `depdesk` parses your Python with the standard library `ast` module, so it
120
+ finds the keyword argument itself, not a string that looks like one.
121
+
122
+ **Endpoints and products** that the provider has put on notice, matched the
123
+ same way.
124
+
125
+ Where the provider's own wording is ambiguous about which models a rule covers,
126
+ `depdesk` says so and downgrades the finding to review instead of guessing.
127
+
128
+ ## Put it in CI
129
+
130
+ This is the point of the exit codes: the build starts failing the day a
131
+ provider gives you notice, not the day the model dies.
132
+
133
+ ```yaml
134
+ # .github/workflows/depdesk.yml
135
+ name: model deprecations
136
+ on:
137
+ push:
138
+ schedule:
139
+ - cron: "0 7 * * 1" # Monday morning, so notice arrives before the deadline
140
+
141
+ jobs:
142
+ check:
143
+ runs-on: ubuntu-latest
144
+ steps:
145
+ - uses: actions/checkout@v4
146
+ - uses: actions/setup-python@v5
147
+ with: { python-version: "3.12" }
148
+ - run: pip install depdesk
149
+ - run: depdesk check . --fail-in 60
150
+ ```
151
+
152
+ | code | meaning |
153
+ | --- | --- |
154
+ | 0 | nothing needs attention |
155
+ | 1 | something is deprecated, but outside the `--fail-in` window |
156
+ | 2 | something is already retired, or retires within `--fail-in` |
157
+ | 3 | the tool could not do its job |
158
+
159
+ ## Weight it by real traffic
160
+
161
+ Scanning code tells you what is referenced. It does not tell you what is hot.
162
+ Point `--usage` at an export and every finding gains a share of traffic, so you
163
+ can tell a dead constant from 40% of production.
164
+
165
+ ```bash
166
+ depdesk check . --usage usage.csv
167
+ depdesk check . --usage usage.csv --usage-count-column input_tokens
168
+ ```
169
+
170
+ ```
171
+ ALREADY RETIRED
172
+
173
+ claude-3-5-sonnet-20241022 [3.3% of measured calls]
174
+ provider: anthropic
175
+ retirement: 2025-10-28 (329 days ago)
176
+ announced: 2025-08-13
177
+ replacement: claude-sonnet-4-6
178
+ seen in usage data but not found anywhere in the scanned tree
179
+
180
+ claude-opus-4-1-20250805 [15.3% of measured calls]
181
+ provider: anthropic
182
+ retirement: 2026-08-05 (48 days ago)
183
+ announced: 2026-06-05
184
+ replacement: claude-opus-4-8
185
+ app/legacy.py:1: OLD = "claude-opus-4-1-20250805"
186
+ ```
187
+
188
+ That first finding is the one worth the flag: a retired model still taking
189
+ traffic from code that is not in this repository at all.
190
+
191
+ For Anthropic: Claude Console, **Usage**, **Export**. The CSV has an API key
192
+ column and a model column, and `depdesk` sniffs them. CSV and JSON both work.
193
+
194
+ ## Ask what breaks later
195
+
196
+ ```bash
197
+ depdesk check . --today 2027-01-01
198
+ ```
199
+
200
+ More useful than it sounds: it answers "what breaks over the holidays" before
201
+ anyone leaves.
202
+
203
+ ## When a finding is not a finding
204
+
205
+ Documentation, changelogs and migration notes legitimately name models that are
206
+ dead. A tool you cannot silence on a line you have already judged is a tool
207
+ people stop running, so there are two escapes, both deliberate:
208
+
209
+ ```python
210
+ OLD = "claude-opus-4-1-20250805" # depdesk: ignore
211
+ ```
212
+
213
+ ```bash
214
+ depdesk check . --exclude "CHANGELOG.md" --exclude "*/migrations/*"
215
+ ```
216
+
217
+ The marker silences one line, in any file type, in whatever comment syntax that
218
+ file uses, because it is matched as text. `--exclude` takes a glob, matched
219
+ against the path and the file name, and repeats. Neither has a project level
220
+ config file on purpose: an ignore list nobody reads is how a tool like this
221
+ starts lying.
222
+
223
+ ## Commands and flags
224
+
225
+ ```
226
+ depdesk check [PATH ...] scan a tree and report what is dying
227
+ depdesk upstream ask whether the provider pages moved
228
+ depdesk list print the catalog
229
+ ```
230
+
231
+ | flag on `check` | what it does |
232
+ | --- | --- |
233
+ | `--fail-in DAYS` | how close a retirement has to be to fail the build (default 90) |
234
+ | `--sunset-in DAYS` | also report active models with an announced earliest retirement inside this window |
235
+ | `--usage FILE` | weight findings by real call volume |
236
+ | `--usage-model-column`, `--usage-count-column` | override the sniffed columns |
237
+ | `--today YYYY-MM-DD` | ask what this repository looks like on a future date |
238
+ | `--locations N` | how many source lines to print per finding (default 3) |
239
+ | `--json` | machine readable output |
240
+ | `--exclude GLOB` | skip paths matching this glob, repeatable |
241
+ | `--no-unknown` | stop reporting identifiers the catalog does not know |
242
+ | `--catalog FILE` | use your own catalog, for a provider we do not cover |
243
+
244
+ ## The catalog, and why you can trust it
245
+
246
+ The only thing that makes this tool worth anything is whether the dates in it
247
+ are true. So they are not hidden: [`depdesk/data/catalog.json`](depdesk/data/catalog.json)
248
+ is plain JSON, every entry was transcribed from the provider's own page, and
249
+ the file records when that happened. `depdesk check` prints a warning when the
250
+ catalog is more than 30 days old.
251
+
252
+ ```bash
253
+ depdesk upstream # did the provider pages change since then?
254
+ depdesk upstream --save # record the current state as the new baseline
255
+ ```
256
+
257
+ `upstream` does not parse the page into a catalog. An earlier version hashed
258
+ the whole page and produced a different digest on three consecutive fetches of
259
+ the same unchanged content, because provider docs carry per-request markup. So
260
+ it extracts the model identifiers and the dates, compares those against the
261
+ catalog, and prints what appeared and what disappeared. A human decides what it
262
+ means. A scraper that half works would produce a catalog that looks maintained
263
+ and is not, which is the exact failure this tool exists to prevent.
264
+
265
+ `upstream` exits 1 when a page moved, 3 when it could not be fetched, and 0
266
+ otherwise. It prints, but does not fail on, the identifiers a page names that
267
+ the catalog does not mention: the OpenAI page alone names 35 of those and
268
+ always will, because a deprecation page also lists models that are not being
269
+ deprecated. That is a standing difference, not an event, and a weekly alarm
270
+ that fires on it stops being read. Pass `--strict` if you do want those to
271
+ fail.
272
+
273
+ This repository runs `upstream` every Monday and
274
+ [opens an issue](.github/workflows/catalog-drift.yml) when a provider page
275
+ moves, so drift lands in front of a person instead of in a log nobody reads.
276
+
277
+ ## What it does not do
278
+
279
+ Being plain about the limits, because the whole point is to be trustworthy:
280
+
281
+ - **It does not know your provider's private schedule.** It knows what is on the
282
+ public deprecation pages, transcribed by hand.
283
+ - **It only covers Anthropic and OpenAI today.** Other providers are a catalog
284
+ entry away, and pull requests are welcome. `--catalog` takes your own file.
285
+ - **It finds identifiers written as text.** A model id assembled at runtime from
286
+ string pieces will not be found by the scanner. The `--usage` path catches
287
+ that case, which is part of why it exists.
288
+ - **It reads `.env` files**, because that is where model configuration lives. It
289
+ prints only lines that matched a model identifier, but if that bothers you,
290
+ scan a narrower path.
291
+ - **It will not edit your code.** Migrating a prompt is a judgement call and this
292
+ tool has no opinion about your prompts.
293
+
294
+ ## Contributing
295
+
296
+ Catalog out of date? A pull request editing `depdesk/data/catalog.json` is the
297
+ fastest path, and the diff is readable by anyone. Want a provider we do not
298
+ cover? Open an issue with a link to their public deprecation page. See
299
+ [CONTRIBUTING.md](CONTRIBUTING.md).
300
+
301
+ ## Development
302
+
303
+ ```bash
304
+ python3 -m pytest -q tests/
305
+ python3 -m depdesk check .
306
+ ```
307
+
308
+ The test suite pins the behaviour that matters: that `gpt-4-turbo` does not
309
+ match inside `gpt-4-turbo-preview`, that an active model stays silent, that the
310
+ parameter rule needs an affected model in the same file before it fires, and
311
+ that the fingerprint survives cosmetic markup changes but not a changed date.
312
+
313
+ ## Licence
314
+
315
+ MIT. Built by [Wendel Ortiz](https://github.com/Ort0x36) while running an LLM
316
+ product in production.
@@ -0,0 +1,288 @@
1
+ # depdesk
2
+
3
+ **Know which of your model calls are on a clock.**
4
+
5
+ [![ci](https://github.com/Ort0x36/deprecation-desk/actions/workflows/ci.yml/badge.svg)](https://github.com/Ort0x36/deprecation-desk/actions/workflows/ci.yml)
6
+ [![pypi](https://img.shields.io/pypi/v/depdesk)](https://pypi.org/project/depdesk/)
7
+ [![python](https://img.shields.io/badge/python-3.9%20to%203.13-blue)](https://www.python.org/downloads/)
8
+ [![dependencies](https://img.shields.io/badge/dependencies-none-brightgreen)](pyproject.toml)
9
+ [![licence](https://img.shields.io/badge/licence-MIT-blue)](LICENSE)
10
+
11
+ Providers retire models on their schedule, not yours. The notice arrives by
12
+ email, to one person, months before anything breaks, and then it is forgotten
13
+ until a request starts failing in production. `depdesk` crosses the deprecation
14
+ notices you did not read with the models your code actually calls, and fails
15
+ your build while there is still time to do something about it.
16
+
17
+ Zero dependencies. Python 3.9 or newer. Anthropic and OpenAI today, and any
18
+ provider you write a catalog entry for.
19
+
20
+ ## Install
21
+
22
+ ```bash
23
+ pip install depdesk
24
+ ```
25
+
26
+ ## Try it in thirty seconds
27
+
28
+ ```bash
29
+ depdesk check .
30
+ ```
31
+
32
+ That is the whole setup. Point it at a repository and it reports every model
33
+ identifier it finds, crossed against the provider's published deprecation
34
+ dates. There is a deliberately broken sample in
35
+ [`examples/legacy-app`](examples/legacy-app) if you want to see a failing run
36
+ before pointing it at your own code.
37
+
38
+ ```
39
+ $ depdesk check . --fail-in 60
40
+ depdesk: 2 files scanned in .
41
+ catalog verified 2026-09-20 (2 days ago)
42
+
43
+ ALREADY RETIRED
44
+
45
+ claude-opus-4-1-20250805
46
+ provider: anthropic
47
+ retirement: 2026-08-05 (48 days ago)
48
+ announced: 2026-06-05
49
+ replacement: claude-opus-4-8
50
+ app/legacy.py:1: OLD = "claude-opus-4-1-20250805"
51
+
52
+ RETIRES SOON
53
+
54
+ gpt-5.4-cyber
55
+ provider: openai
56
+ retirement: 2026-10-01 (9 days left)
57
+ announced: 2026-09-11
58
+ replacement: gpt-5.6-cyber
59
+ app/legacy.py:2: CYBER = "gpt-5.4-cyber"
60
+
61
+ DEPRECATED PARAMETERS
62
+
63
+ temperature
64
+ behaviour: Returns a 400 error when set to a non-default value.
65
+ replacement: Omit the parameter and steer behaviour through prompting.
66
+ sdk: The Python SDK (v1.0 and later) removes temperature, top_p
67
+ and top_k, so passing them raises a TypeError.
68
+ app/legacy.py:9: temperature=0,
69
+ file also names: claude-opus-5
70
+
71
+ Summary: 1 already retired, 1 retires soon.
72
+ $ echo $?
73
+ 2
74
+ ```
75
+
76
+ Every line of that output is real: it is the tool running against a two file
77
+ sample, not a mockup.
78
+
79
+ ## What it finds
80
+
81
+ **Models on a clock.** Identifiers written anywhere in the tree, including
82
+ `.env` files and config, matched against the provider's own retirement dates.
83
+ Each finding carries the announcement date, the retirement date, the
84
+ replacement the provider names, and the exact lines where you use it.
85
+
86
+ **Deprecated parameters.** Model retirement is the loud failure. The quiet one
87
+ is a parameter that starts returning 400 on newer models while your code keeps
88
+ passing it, which is what happened to `temperature`, `top_p` and `top_k` on
89
+ Claude Opus 4.7 and later. No changelog files that under "deprecation", and
90
+ nothing in your test suite catches it if your tests never hit the new model.
91
+ `depdesk` parses your Python with the standard library `ast` module, so it
92
+ finds the keyword argument itself, not a string that looks like one.
93
+
94
+ **Endpoints and products** that the provider has put on notice, matched the
95
+ same way.
96
+
97
+ Where the provider's own wording is ambiguous about which models a rule covers,
98
+ `depdesk` says so and downgrades the finding to review instead of guessing.
99
+
100
+ ## Put it in CI
101
+
102
+ This is the point of the exit codes: the build starts failing the day a
103
+ provider gives you notice, not the day the model dies.
104
+
105
+ ```yaml
106
+ # .github/workflows/depdesk.yml
107
+ name: model deprecations
108
+ on:
109
+ push:
110
+ schedule:
111
+ - cron: "0 7 * * 1" # Monday morning, so notice arrives before the deadline
112
+
113
+ jobs:
114
+ check:
115
+ runs-on: ubuntu-latest
116
+ steps:
117
+ - uses: actions/checkout@v4
118
+ - uses: actions/setup-python@v5
119
+ with: { python-version: "3.12" }
120
+ - run: pip install depdesk
121
+ - run: depdesk check . --fail-in 60
122
+ ```
123
+
124
+ | code | meaning |
125
+ | --- | --- |
126
+ | 0 | nothing needs attention |
127
+ | 1 | something is deprecated, but outside the `--fail-in` window |
128
+ | 2 | something is already retired, or retires within `--fail-in` |
129
+ | 3 | the tool could not do its job |
130
+
131
+ ## Weight it by real traffic
132
+
133
+ Scanning code tells you what is referenced. It does not tell you what is hot.
134
+ Point `--usage` at an export and every finding gains a share of traffic, so you
135
+ can tell a dead constant from 40% of production.
136
+
137
+ ```bash
138
+ depdesk check . --usage usage.csv
139
+ depdesk check . --usage usage.csv --usage-count-column input_tokens
140
+ ```
141
+
142
+ ```
143
+ ALREADY RETIRED
144
+
145
+ claude-3-5-sonnet-20241022 [3.3% of measured calls]
146
+ provider: anthropic
147
+ retirement: 2025-10-28 (329 days ago)
148
+ announced: 2025-08-13
149
+ replacement: claude-sonnet-4-6
150
+ seen in usage data but not found anywhere in the scanned tree
151
+
152
+ claude-opus-4-1-20250805 [15.3% of measured calls]
153
+ provider: anthropic
154
+ retirement: 2026-08-05 (48 days ago)
155
+ announced: 2026-06-05
156
+ replacement: claude-opus-4-8
157
+ app/legacy.py:1: OLD = "claude-opus-4-1-20250805"
158
+ ```
159
+
160
+ That first finding is the one worth the flag: a retired model still taking
161
+ traffic from code that is not in this repository at all.
162
+
163
+ For Anthropic: Claude Console, **Usage**, **Export**. The CSV has an API key
164
+ column and a model column, and `depdesk` sniffs them. CSV and JSON both work.
165
+
166
+ ## Ask what breaks later
167
+
168
+ ```bash
169
+ depdesk check . --today 2027-01-01
170
+ ```
171
+
172
+ More useful than it sounds: it answers "what breaks over the holidays" before
173
+ anyone leaves.
174
+
175
+ ## When a finding is not a finding
176
+
177
+ Documentation, changelogs and migration notes legitimately name models that are
178
+ dead. A tool you cannot silence on a line you have already judged is a tool
179
+ people stop running, so there are two escapes, both deliberate:
180
+
181
+ ```python
182
+ OLD = "claude-opus-4-1-20250805" # depdesk: ignore
183
+ ```
184
+
185
+ ```bash
186
+ depdesk check . --exclude "CHANGELOG.md" --exclude "*/migrations/*"
187
+ ```
188
+
189
+ The marker silences one line, in any file type, in whatever comment syntax that
190
+ file uses, because it is matched as text. `--exclude` takes a glob, matched
191
+ against the path and the file name, and repeats. Neither has a project level
192
+ config file on purpose: an ignore list nobody reads is how a tool like this
193
+ starts lying.
194
+
195
+ ## Commands and flags
196
+
197
+ ```
198
+ depdesk check [PATH ...] scan a tree and report what is dying
199
+ depdesk upstream ask whether the provider pages moved
200
+ depdesk list print the catalog
201
+ ```
202
+
203
+ | flag on `check` | what it does |
204
+ | --- | --- |
205
+ | `--fail-in DAYS` | how close a retirement has to be to fail the build (default 90) |
206
+ | `--sunset-in DAYS` | also report active models with an announced earliest retirement inside this window |
207
+ | `--usage FILE` | weight findings by real call volume |
208
+ | `--usage-model-column`, `--usage-count-column` | override the sniffed columns |
209
+ | `--today YYYY-MM-DD` | ask what this repository looks like on a future date |
210
+ | `--locations N` | how many source lines to print per finding (default 3) |
211
+ | `--json` | machine readable output |
212
+ | `--exclude GLOB` | skip paths matching this glob, repeatable |
213
+ | `--no-unknown` | stop reporting identifiers the catalog does not know |
214
+ | `--catalog FILE` | use your own catalog, for a provider we do not cover |
215
+
216
+ ## The catalog, and why you can trust it
217
+
218
+ The only thing that makes this tool worth anything is whether the dates in it
219
+ are true. So they are not hidden: [`depdesk/data/catalog.json`](depdesk/data/catalog.json)
220
+ is plain JSON, every entry was transcribed from the provider's own page, and
221
+ the file records when that happened. `depdesk check` prints a warning when the
222
+ catalog is more than 30 days old.
223
+
224
+ ```bash
225
+ depdesk upstream # did the provider pages change since then?
226
+ depdesk upstream --save # record the current state as the new baseline
227
+ ```
228
+
229
+ `upstream` does not parse the page into a catalog. An earlier version hashed
230
+ the whole page and produced a different digest on three consecutive fetches of
231
+ the same unchanged content, because provider docs carry per-request markup. So
232
+ it extracts the model identifiers and the dates, compares those against the
233
+ catalog, and prints what appeared and what disappeared. A human decides what it
234
+ means. A scraper that half works would produce a catalog that looks maintained
235
+ and is not, which is the exact failure this tool exists to prevent.
236
+
237
+ `upstream` exits 1 when a page moved, 3 when it could not be fetched, and 0
238
+ otherwise. It prints, but does not fail on, the identifiers a page names that
239
+ the catalog does not mention: the OpenAI page alone names 35 of those and
240
+ always will, because a deprecation page also lists models that are not being
241
+ deprecated. That is a standing difference, not an event, and a weekly alarm
242
+ that fires on it stops being read. Pass `--strict` if you do want those to
243
+ fail.
244
+
245
+ This repository runs `upstream` every Monday and
246
+ [opens an issue](.github/workflows/catalog-drift.yml) when a provider page
247
+ moves, so drift lands in front of a person instead of in a log nobody reads.
248
+
249
+ ## What it does not do
250
+
251
+ Being plain about the limits, because the whole point is to be trustworthy:
252
+
253
+ - **It does not know your provider's private schedule.** It knows what is on the
254
+ public deprecation pages, transcribed by hand.
255
+ - **It only covers Anthropic and OpenAI today.** Other providers are a catalog
256
+ entry away, and pull requests are welcome. `--catalog` takes your own file.
257
+ - **It finds identifiers written as text.** A model id assembled at runtime from
258
+ string pieces will not be found by the scanner. The `--usage` path catches
259
+ that case, which is part of why it exists.
260
+ - **It reads `.env` files**, because that is where model configuration lives. It
261
+ prints only lines that matched a model identifier, but if that bothers you,
262
+ scan a narrower path.
263
+ - **It will not edit your code.** Migrating a prompt is a judgement call and this
264
+ tool has no opinion about your prompts.
265
+
266
+ ## Contributing
267
+
268
+ Catalog out of date? A pull request editing `depdesk/data/catalog.json` is the
269
+ fastest path, and the diff is readable by anyone. Want a provider we do not
270
+ cover? Open an issue with a link to their public deprecation page. See
271
+ [CONTRIBUTING.md](CONTRIBUTING.md).
272
+
273
+ ## Development
274
+
275
+ ```bash
276
+ python3 -m pytest -q tests/
277
+ python3 -m depdesk check .
278
+ ```
279
+
280
+ The test suite pins the behaviour that matters: that `gpt-4-turbo` does not
281
+ match inside `gpt-4-turbo-preview`, that an active model stays silent, that the
282
+ parameter rule needs an affected model in the same file before it fires, and
283
+ that the fingerprint survives cosmetic markup changes but not a changed date.
284
+
285
+ ## Licence
286
+
287
+ MIT. Built by [Wendel Ortiz](https://github.com/Ort0x36) while running an LLM
288
+ product in production.
@@ -0,0 +1,3 @@
1
+ """depdesk: know which of your model calls are on a clock."""
2
+
3
+ __version__ = "0.1.0"