sg-groundtruth 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.
@@ -0,0 +1,28 @@
1
+ .env.local
2
+ __pycache__/
3
+ *.pyc
4
+ .venv/
5
+ .schema-cache/
6
+ *.local.json
7
+ .DS_Store
8
+ .idea/
9
+ .vscode/
10
+ corpus.local/
11
+ .playwright-mcp/
12
+ node_modules/
13
+ .svelte-kit/
14
+ site/build/
15
+ dist/
16
+ *.egg-info/
17
+
18
+ # No longer written: the default lives in site/vite.config.js so a fresh clone builds unconfigured.
19
+ site/.env
20
+
21
+ # Stray screenshots
22
+ /page.png
23
+
24
+ # Live status icons, fetched at build time from the configured site (site/scripts/
25
+ # fetch-status-icons.mjs). Never committed: the sprite is the vendor's artwork, and the
26
+ # deploy fetches its own copy from the env vars set on Vercel.
27
+ site/static/status-sprite.png
28
+ site/src/lib/content/status-icons.json
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kevin Sallee and contributors
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.
@@ -0,0 +1,136 @@
1
+ Metadata-Version: 2.5
2
+ Name: sg-groundtruth
3
+ Version: 0.1.0
4
+ Summary: Thin Flow Production Tracking REST client, and an MCP server for the recorded-behaviour corpus that documents it
5
+ Project-URL: Homepage, https://github.com/ksallee/sg-groundtruth
6
+ Project-URL: Source, https://github.com/ksallee/sg-groundtruth
7
+ Project-URL: Issues, https://github.com/ksallee/sg-groundtruth/issues
8
+ Author: Kevin Sallee
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: autodesk,flow-production-tracking,mcp,shotgrid,shotgun,vfx
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Multimedia :: Graphics
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Requires-Python: >=3.11
20
+ Requires-Dist: requests>=2.28
21
+ Description-Content-Type: text/markdown
22
+
23
+ # SG Ground Truth
24
+
25
+ Recorded behaviour of the Flow Production Tracking REST API.
26
+
27
+ The REST documentation is incomplete and in places wrong. Every entry here is what a live Flow PT site
28
+ answered when a probe asked it one question: the status code, the error string, the response shape, in
29
+ the words the API used. The 51 probes that produced it are in this repository and run against any site.
30
+
31
+ ## Read it
32
+
33
+ git clone https://github.com/ksallee/sg-groundtruth
34
+
35
+ Then give an agent one line:
36
+
37
+ Read sg-groundtruth/corpus/INDEX.md first.
38
+ Open an entry only when its one-liner falls short.
39
+
40
+ `corpus/INDEX.md` is generated: 67 KB, one line per entry with its verdict and its tags. The corpus
41
+ behind it is much larger, and an agent that loads all of it spends its context on the first call.
42
+
43
+ ## What is in `corpus/`
44
+
45
+ | directory | holds |
46
+ |---|---|
47
+ | `endpoints/` | 64 cards, one per REST call: what it takes, every status code it answers with, a recorded response |
48
+ | `findings/entity_types/` | 17 cards, one per schema name: identity, the create contract, every link field, the status field |
49
+ | `findings/field_types/` | 24 cards, one per `data_type`: what it reads, writes and clears as, and what filters it |
50
+ | `findings/` | 40 questions, each answered by one probe, grouped by the phase of a session they bite in |
51
+ | `recipes/` | 11 tasks, each with the calls that perform it, the real response, and the errors hit on the way |
52
+ | `INDEX.md` | generated. Read this first |
53
+
54
+ Four ways in, one per thing a caller already knows before making a call: the call itself, the entity
55
+ type, the field's `data_type`, or the task.
56
+
57
+ ## Why it exists
58
+
59
+ A 400 names the legal set and an agent recovers from it. A 200 that ignored what you sent teaches it
60
+ nothing. Each row is a published finding.
61
+
62
+ | you do this | this happens |
63
+ |---|---|
64
+ | Sort on a misspelled field | `200`. The sort is ignored, rows come back id ascending, and nothing says so |
65
+ | Page until `links.next` is absent | It is never absent. It is emitted on zero-row pages too. Stop when `data` is empty |
66
+ | Create rows in a batch | You get an id per row. A batch can return an id for a row it never made |
67
+ | Create a field whose display name is taken | `201`. You got `<name>_1` |
68
+
69
+ ## Mount it over MCP
70
+
71
+ PYTHONPATH=src python -m sg_groundtruth.mcp
72
+
73
+ Five tools, stdio, standard library only, so mounting it costs nothing beyond the clone. `PYTHONPATH`
74
+ is not optional: the package is not installed. Registration for Claude Code and any other stdio client
75
+ is in [docs/mcp.md](docs/mcp.md).
76
+
77
+ It answers what the API does. A Flow PT MCP server calls the API. An agent given both has to be told
78
+ which is which.
79
+
80
+ ## Put your own site in it
81
+
82
+ The corpus covers any Flow PT site. One command measures yours: your custom entities, your field
83
+ names, your status vocabularies, your projects.
84
+
85
+ cd sg-groundtruth
86
+ claude
87
+
88
+ Then ask for `/sg-groundtruth-setup`. Start the agent inside the clone: the command is one of this
89
+ repository's own and is registered when the session starts.
90
+
91
+ | | |
92
+ |---|---|
93
+ | Writes to your site | Nothing, unless a probe is run with `--write` |
94
+ | Project it may write into | The sandbox you name, and no other |
95
+ | Where your data goes | `corpus.local/`, gitignored, never leaves your machine |
96
+
97
+ ## Scopes
98
+
99
+ Every entry declares one, because a measurement that is true of one site is not a fact about the API.
100
+
101
+ | scope | true of | committed |
102
+ |---|---|---|
103
+ | `api` | Any Flow PT site: status codes, error strings, value shapes, operator vocabularies | Yes |
104
+ | `site` | One site: which custom entities are enabled, which fields exist, `valid_values` | Only when scrubbed |
105
+ | `project` | One project inside it: `hidden_values`, page columns, fill rates | No |
106
+
107
+ `valid_values` is byte-identical at every scope and only `hidden_values` varies by project, so "which
108
+ statuses can I use" has no site-level answer. That is why the last two are not one scope (probe 009).
109
+
110
+ ## Probes
111
+
112
+ python probes/017_filter_operators.py
113
+
114
+ One question per probe. A probe prints what the API answered and deletes anything it created before it
115
+ exits; it never writes the corpus. An agent reads the output and writes the entry. Every entry names
116
+ the probe that produced it, so a claim you doubt, you re-run.
117
+
118
+ Read-only by default. A write needs `--write`, and the only project a probe may write into is the
119
+ sandbox named in `.env.local`.
120
+
121
+ ## Layout
122
+
123
+ | path | |
124
+ |---|---|
125
+ | `corpus/` | the corpus. `scope: api`, committed, the product |
126
+ | `probes/` | the scripts that produced it, plus `check_corpus.py` and `index.py` |
127
+ | `src/sg_groundtruth/` | the MCP server, the schema inspector, the client |
128
+ | `site/` | SvelteKit, prerendered static, renders the corpus and any local overlay |
129
+ | `docs/` | MCP registration, the example overlay, unverified operator claims |
130
+ | `corpus.local/` | your own site, written by the setup command. Gitignored |
131
+
132
+ ## Licence
133
+
134
+ [MIT](LICENSE). Nothing AGPL enters this repository, at any depth. It is derived only from the public
135
+ Flow PT REST documentation and this repository's own probes, so that studio legal can say yes without
136
+ reading anything.
@@ -0,0 +1,114 @@
1
+ # SG Ground Truth
2
+
3
+ Recorded behaviour of the Flow Production Tracking REST API.
4
+
5
+ The REST documentation is incomplete and in places wrong. Every entry here is what a live Flow PT site
6
+ answered when a probe asked it one question: the status code, the error string, the response shape, in
7
+ the words the API used. The 51 probes that produced it are in this repository and run against any site.
8
+
9
+ ## Read it
10
+
11
+ git clone https://github.com/ksallee/sg-groundtruth
12
+
13
+ Then give an agent one line:
14
+
15
+ Read sg-groundtruth/corpus/INDEX.md first.
16
+ Open an entry only when its one-liner falls short.
17
+
18
+ `corpus/INDEX.md` is generated: 67 KB, one line per entry with its verdict and its tags. The corpus
19
+ behind it is much larger, and an agent that loads all of it spends its context on the first call.
20
+
21
+ ## What is in `corpus/`
22
+
23
+ | directory | holds |
24
+ |---|---|
25
+ | `endpoints/` | 64 cards, one per REST call: what it takes, every status code it answers with, a recorded response |
26
+ | `findings/entity_types/` | 17 cards, one per schema name: identity, the create contract, every link field, the status field |
27
+ | `findings/field_types/` | 24 cards, one per `data_type`: what it reads, writes and clears as, and what filters it |
28
+ | `findings/` | 40 questions, each answered by one probe, grouped by the phase of a session they bite in |
29
+ | `recipes/` | 11 tasks, each with the calls that perform it, the real response, and the errors hit on the way |
30
+ | `INDEX.md` | generated. Read this first |
31
+
32
+ Four ways in, one per thing a caller already knows before making a call: the call itself, the entity
33
+ type, the field's `data_type`, or the task.
34
+
35
+ ## Why it exists
36
+
37
+ A 400 names the legal set and an agent recovers from it. A 200 that ignored what you sent teaches it
38
+ nothing. Each row is a published finding.
39
+
40
+ | you do this | this happens |
41
+ |---|---|
42
+ | Sort on a misspelled field | `200`. The sort is ignored, rows come back id ascending, and nothing says so |
43
+ | Page until `links.next` is absent | It is never absent. It is emitted on zero-row pages too. Stop when `data` is empty |
44
+ | Create rows in a batch | You get an id per row. A batch can return an id for a row it never made |
45
+ | Create a field whose display name is taken | `201`. You got `<name>_1` |
46
+
47
+ ## Mount it over MCP
48
+
49
+ PYTHONPATH=src python -m sg_groundtruth.mcp
50
+
51
+ Five tools, stdio, standard library only, so mounting it costs nothing beyond the clone. `PYTHONPATH`
52
+ is not optional: the package is not installed. Registration for Claude Code and any other stdio client
53
+ is in [docs/mcp.md](docs/mcp.md).
54
+
55
+ It answers what the API does. A Flow PT MCP server calls the API. An agent given both has to be told
56
+ which is which.
57
+
58
+ ## Put your own site in it
59
+
60
+ The corpus covers any Flow PT site. One command measures yours: your custom entities, your field
61
+ names, your status vocabularies, your projects.
62
+
63
+ cd sg-groundtruth
64
+ claude
65
+
66
+ Then ask for `/sg-groundtruth-setup`. Start the agent inside the clone: the command is one of this
67
+ repository's own and is registered when the session starts.
68
+
69
+ | | |
70
+ |---|---|
71
+ | Writes to your site | Nothing, unless a probe is run with `--write` |
72
+ | Project it may write into | The sandbox you name, and no other |
73
+ | Where your data goes | `corpus.local/`, gitignored, never leaves your machine |
74
+
75
+ ## Scopes
76
+
77
+ Every entry declares one, because a measurement that is true of one site is not a fact about the API.
78
+
79
+ | scope | true of | committed |
80
+ |---|---|---|
81
+ | `api` | Any Flow PT site: status codes, error strings, value shapes, operator vocabularies | Yes |
82
+ | `site` | One site: which custom entities are enabled, which fields exist, `valid_values` | Only when scrubbed |
83
+ | `project` | One project inside it: `hidden_values`, page columns, fill rates | No |
84
+
85
+ `valid_values` is byte-identical at every scope and only `hidden_values` varies by project, so "which
86
+ statuses can I use" has no site-level answer. That is why the last two are not one scope (probe 009).
87
+
88
+ ## Probes
89
+
90
+ python probes/017_filter_operators.py
91
+
92
+ One question per probe. A probe prints what the API answered and deletes anything it created before it
93
+ exits; it never writes the corpus. An agent reads the output and writes the entry. Every entry names
94
+ the probe that produced it, so a claim you doubt, you re-run.
95
+
96
+ Read-only by default. A write needs `--write`, and the only project a probe may write into is the
97
+ sandbox named in `.env.local`.
98
+
99
+ ## Layout
100
+
101
+ | path | |
102
+ |---|---|
103
+ | `corpus/` | the corpus. `scope: api`, committed, the product |
104
+ | `probes/` | the scripts that produced it, plus `check_corpus.py` and `index.py` |
105
+ | `src/sg_groundtruth/` | the MCP server, the schema inspector, the client |
106
+ | `site/` | SvelteKit, prerendered static, renders the corpus and any local overlay |
107
+ | `docs/` | MCP registration, the example overlay, unverified operator claims |
108
+ | `corpus.local/` | your own site, written by the setup command. Gitignored |
109
+
110
+ ## Licence
111
+
112
+ [MIT](LICENSE). Nothing AGPL enters this repository, at any depth. It is derived only from the public
113
+ Flow PT REST documentation and this repository's own probes, so that studio legal can say yes without
114
+ reading anything.
@@ -0,0 +1,17 @@
1
+ # Endpoint cards
2
+
3
+ One card per REST call, named by the call. The card holds what is true of the endpoint rather than of a
4
+ data type or an entity type: what it takes, what it answers, what a real response looks like, and the
5
+ edge cases that live on the call.
6
+
7
+ It does not restate a finding. Every finding and recipe names its `endpoints:`, and the index and the
8
+ site render those verdicts under the card, so the quirks are on the page without being written twice.
9
+
10
+ `endpoint:` is the canonical spelling and the identity. `<type>` is the plural URL segment, `<Type>` the
11
+ schema name, `<id>` a row id, `<field>` a field name.
12
+
13
+ Every card states `coverage:`: `measured` when every call on it was made and answered, otherwise
14
+ `partial` or `untested` with an `unmeasured:` line saying what was not reached. A card is the unit a
15
+ docs sweep adds, so it is written before anything has been probed and the key is what keeps that
16
+ visible. The index and the site badge anything that is not `measured` and repeat the reason on the
17
+ row and on the page.
@@ -0,0 +1,14 @@
1
+ # Run 3
2
+
3
+ The grading material and the seed inventory are deliberately **not here** while the run is in progress.
4
+
5
+ Arm a is given the whole repository, including `probes/`, the schema inspector, the MCP server and the
6
+ slash commands, because that is what someone who clones this actually has. An answer key stored inside
7
+ the repository would be part of what that arm can read.
8
+
9
+ During the run they live in `~/dev/run3-grading/`, which no arm can reach: arm a is scoped to this
10
+ repository, arms b and c are scoped to their own directories. They come back here with the result.
11
+
12
+ `experiments/weekly-report/` stays where it is. It records a previous run and names several of the same
13
+ traps. Arm a can read it, and a person who cloned this repository could too, so that is a real advantage
14
+ rather than a leak. `RESULT.md` has to say whether arm a used it.
@@ -0,0 +1,41 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "sg-groundtruth"
7
+ version = "0.1.0"
8
+ description = "Thin Flow Production Tracking REST client, and an MCP server for the recorded-behaviour corpus that documents it"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "Kevin Sallee" }]
14
+ keywords = ["shotgrid", "shotgun", "flow-production-tracking", "autodesk", "vfx", "mcp"]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Developers",
18
+ "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ "Programming Language :: Python :: 3.13",
21
+ "Topic :: Multimedia :: Graphics",
22
+ "Topic :: Software Development :: Libraries :: Python Modules",
23
+ ]
24
+ dependencies = ["requests>=2.28"]
25
+
26
+ [project.urls]
27
+ Homepage = "https://github.com/ksallee/sg-groundtruth"
28
+ Source = "https://github.com/ksallee/sg-groundtruth"
29
+ Issues = "https://github.com/ksallee/sg-groundtruth/issues"
30
+
31
+ [project.scripts]
32
+ sg-groundtruth-mcp = "sg_groundtruth.mcp:main"
33
+
34
+ # The wheel is the client and the tools, never the corpus. The corpus is read from a clone, because
35
+ # every entry names the probe that produced it and re-running that probe is the point; a corpus
36
+ # frozen into a release is one nobody can check. `mcp.py` says so when it cannot find one.
37
+ [tool.hatch.build.targets.wheel]
38
+ packages = ["src/sg_groundtruth"]
39
+
40
+ [tool.hatch.build.targets.sdist]
41
+ include = ["src/sg_groundtruth", "README.md", "LICENSE"]