Developers › File formats Beta
WorkspacePacks.json
Status: generated from the web's packs. No version field: the file has no
schemaVersion and no kind.
WorkspacePacks.json holds the starting rubric for each kind of shelf that
has one, as the web defines it, so that "Literary Contest" means the same
criteria in the web app and the Mac app. It lives in the repository at
native/Packages/ShelfCore/Sources/ShelfCore/Resources/WorkspacePacks.json
and ships inside ShelfCore as a resource.
How it is made
- The source is
WORKSPACE_PACKSintextshelf/submissions/workspace_packs.py. The file is never edited by hand. uv run python manage.py export_workspace_packswrites it. It writes nothing when the file is already current.uv run python manage.py export_workspace_packs --checkwrites nothing. It fails (exit status 1, "… is out of date; run manage.py export_workspace_packs.") when the file differs from the packs or is missing.- The one serializer is
packs_as_json():json.dumps(data, indent=2, ensure_ascii=False) + "\n". Keys are in the order shown below, not sorted. Packs are inWORKSPACE_PACKSorder. The file ends in one newline and has no trailing spaces.
How it is checked
- Web tests in
textshelf/submissions/tests/test_workspace_packs.py:test_the_checked_in_file_matches_the_packscompares the file topacks_as_json()byte for byte and fails if the file is missing;test_the_file_passes_the_whitespace_hookschecks the ending and trailing spaces;test_check_fails_on_a_stale_fileruns--checkagainst a missing file, then a written one.test_every_pack_is_valid_shelf_datachecks that criterion names are unique and that each phrase's kind is one of the five below and its text is 2 to 100 characters. - Swift tests in
native/Packages/ShelfCore/Tests/ShelfCoreTests/WorkspacePackTests.swiftpin every pack's field ids and check the rubric made from each pack. - No workflow runs
--check. The Django CI workflow skips pull requests that change only files undernative/, so a hand edit to the JSON alone is not compared with the packs by CI. The Swift tests catch such an edit only when it changes a field id or the set of packs, or empties a description.
Shape
One JSON object. Each key is a web workspace_type; each value is that
kind's pack. Today there are three: literary_contest, grant_program and
academic_review. Kinds with no pack (custom, and the web's other kinds)
are absent.
| Key | Type | Meaning | Read by the Mac |
|---|---|---|---|
label |
string | The web's name for the kind of program, such as literary contests. |
no |
criteria |
array | The starting criteria, in order. | yes, required |
criteria[].name |
string | The criterion's name. | yes, required |
criteria[].description |
string | What the criterion asks. | yes, required |
criteria[].weight |
number | The web's weight. 1.0 in every pack today. |
no |
criteria[].max_score |
integer | Highest score. 5 in every pack today. |
yes, required |
phrases |
array of [kind, text] pairs |
Quick feedback phrases the web seeds a new shelf with. kind is praise, suggestion, question, issue or note. |
no |
The Mac ignores keys it doesn't use. If the file is missing, or anything the Mac reads is missing or of the wrong type in any pack, the whole file fails: every kind then starts with an empty rubric, and debug builds stop with an assertion. A pack under a key the Mac has no kind for is loaded and never used.
Abridged (one criterion and two phrases of the literary pack):
{
"literary_contest": {
"label": "literary contests",
"criteria": [
{
"name": "Voice",
"description": "Language that sounds like this writer and no one else: controlled, specific, and alive on the page, or in the mouth for a play.",
"weight": 1.0,
"max_score": 5
}
],
"phrases": [
[
"praise",
"Distinct voice"
],
[
"suggestion",
"Tension drops here"
]
]
}
}
What the Mac makes of a pack
A new shelf of a kind with a pack gets this rubric in settings.json
(shelf-bundle.md §5.2):
- one
scorefield per criterion, in order:idfrom the name (below),labelthe name,min1,maxthemax_score,helpthe description; - then
{"id": "notes", "label": "Notes", "type": "text"}.
The field ids are also written as seededFieldIDs. custom gets an empty
rubric and never reads the file.
A field id is the criterion name with accents folded and letters lowercased,
keeping ASCII letters and digits, with each run of anything else turned into
one _, and none at either end. "Craft and finish" becomes
craft_and_finish. The ids are stored in shelves, so the Swift tests pin
them:
| Kind | Field ids |
|---|---|
literary_contest |
voice, structure, stakes, craft_and_finish, notes |
grant_program |
need_and_significance, approach, capacity, budget, outcomes_and_evaluation, notes |
academic_review |
originality, significance, methods, evidence_and_conclusions, clarity, notes |
A renamed criterion, or a change to this rule, changes only what new shelves get. Saved shelves keep the ids they were written with.
Who reads it
- ShelfCore's
WorkspacePacks, which the Mac app uses for: - the rubric of a new shelf (File ▸ New, and the kind menu when it replaces an untouched starting rubric);
- the rubric of a shelf opened with no
settings.json, in the app and in its Quick Look extension; - the line of criterion names under each kind in the New Shelf menu;
- the rubric editor's "Replace with … preset" items, one per kind with a pack.
- The web reads the file only in its test and the export command. It never
reads it at runtime: the deployed image excludes
native/(.dockerignore). The web seeds its own shelves fromWORKSPACE_PACKSdirectly.
Where the code is
textshelf/submissions/workspace_packs.py:38-52(the dataclasses),:211-215(WORKSPACE_PACKS),:222-246(packs_as_json).textshelf/submissions/management/commands/export_workspace_packs.py:24-62.textshelf/submissions/tests/test_workspace_packs.py:45-63,:238-268.native/Packages/ShelfCore/Sources/ShelfCore/WorkspacePacks.swift:15-112.native/Packages/ShelfCore/Sources/ShelfCore/Models.swift:174-180(ShelfSettings.seeded),:209-211(Rubric.defaultFor).native/Packages/ShelfCore/Sources/ShelfCore/ShelfDocument.swift:184-191(the fallback whensettings.jsonis missing).native/Packages/ShelfCore/Tests/ShelfCoreTests/WorkspacePackTests.swift:15-26.native/Packages/ShelfCore/Package.swift:15-16(the resource).native/Packages/ShelfUI/Sources/ShelfUI/NewShelfKindMenu.swift:36-41,native/Packages/ShelfUI/Sources/ShelfUI/RubricEditorView.swift:83-89..github/workflows/django.yml:4-18;.dockerignore:62.
This specification is licensed under CC BY 4.0; the example files under MIT. Anyone may implement these formats in their own software.
This specification is licensed under CC BY 4.0, and its example and schema files under the MIT licence. Anyone may implement these formats in their own software. CC BY 4.0