masterwork 0.0.3__tar.gz → 0.0.4__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 (41) hide show
  1. {masterwork-0.0.3/masterwork.egg-info → masterwork-0.0.4}/PKG-INFO +23 -23
  2. {masterwork-0.0.3 → masterwork-0.0.4}/README.md +2 -2
  3. {masterwork-0.0.3 → masterwork-0.0.4}/README.pypi.md +22 -22
  4. {masterwork-0.0.3 → masterwork-0.0.4}/masterwork/__init__.py +1 -1
  5. {masterwork-0.0.3 → masterwork-0.0.4}/masterwork/__main__.py +33 -0
  6. masterwork-0.0.4/masterwork/starter/script.json +19 -0
  7. masterwork-0.0.4/masterwork/starter/tales.md +77 -0
  8. {masterwork-0.0.3 → masterwork-0.0.4/masterwork.egg-info}/PKG-INFO +23 -23
  9. {masterwork-0.0.3 → masterwork-0.0.4}/masterwork.egg-info/SOURCES.txt +2 -0
  10. {masterwork-0.0.3 → masterwork-0.0.4}/pyproject.toml +2 -2
  11. {masterwork-0.0.3 → masterwork-0.0.4}/tests/test_cli.py +16 -1
  12. {masterwork-0.0.3 → masterwork-0.0.4}/LICENSE +0 -0
  13. {masterwork-0.0.3 → masterwork-0.0.4}/masterwork/blind_label.py +0 -0
  14. {masterwork-0.0.3 → masterwork-0.0.4}/masterwork/campaign.py +0 -0
  15. {masterwork-0.0.3 → masterwork-0.0.4}/masterwork/cells.py +0 -0
  16. {masterwork-0.0.3 → masterwork-0.0.4}/masterwork/ceremony.py +0 -0
  17. {masterwork-0.0.3 → masterwork-0.0.4}/masterwork/gate.py +0 -0
  18. {masterwork-0.0.3 → masterwork-0.0.4}/masterwork/line.py +0 -0
  19. {masterwork-0.0.3 → masterwork-0.0.4}/masterwork/measure.py +0 -0
  20. {masterwork-0.0.3 → masterwork-0.0.4}/masterwork/pairs.py +0 -0
  21. {masterwork-0.0.3 → masterwork-0.0.4}/masterwork/retain.py +0 -0
  22. {masterwork-0.0.3 → masterwork-0.0.4}/masterwork/rubric-example.json +0 -0
  23. {masterwork-0.0.3 → masterwork-0.0.4}/masterwork/seal.py +0 -0
  24. {masterwork-0.0.3 → masterwork-0.0.4}/masterwork.egg-info/dependency_links.txt +0 -0
  25. {masterwork-0.0.3 → masterwork-0.0.4}/masterwork.egg-info/entry_points.txt +0 -0
  26. {masterwork-0.0.3 → masterwork-0.0.4}/masterwork.egg-info/requires.txt +0 -0
  27. {masterwork-0.0.3 → masterwork-0.0.4}/masterwork.egg-info/top_level.txt +0 -0
  28. {masterwork-0.0.3 → masterwork-0.0.4}/setup.cfg +0 -0
  29. {masterwork-0.0.3 → masterwork-0.0.4}/tests/test_badges.py +0 -0
  30. {masterwork-0.0.3 → masterwork-0.0.4}/tests/test_blind_label.py +0 -0
  31. {masterwork-0.0.3 → masterwork-0.0.4}/tests/test_campaign.py +0 -0
  32. {masterwork-0.0.3 → masterwork-0.0.4}/tests/test_cells.py +0 -0
  33. {masterwork-0.0.3 → masterwork-0.0.4}/tests/test_ceremony.py +0 -0
  34. {masterwork-0.0.3 → masterwork-0.0.4}/tests/test_examples.py +0 -0
  35. {masterwork-0.0.3 → masterwork-0.0.4}/tests/test_gate.py +0 -0
  36. {masterwork-0.0.3 → masterwork-0.0.4}/tests/test_line.py +0 -0
  37. {masterwork-0.0.3 → masterwork-0.0.4}/tests/test_measure.py +0 -0
  38. {masterwork-0.0.3 → masterwork-0.0.4}/tests/test_packaging.py +0 -0
  39. {masterwork-0.0.3 → masterwork-0.0.4}/tests/test_pairs.py +0 -0
  40. {masterwork-0.0.3 → masterwork-0.0.4}/tests/test_retain.py +0 -0
  41. {masterwork-0.0.3 → masterwork-0.0.4}/tests/test_seal.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: masterwork
3
- Version: 0.0.3
3
+ Version: 0.0.4
4
4
  Summary: A production line for agent character: a sitting the model speaks for itself in, sealed candidates, frozen gates, and a verdict it is not allowed to give itself.
5
5
  Author: Codechu
6
6
  License-Expression: Apache-2.0
@@ -25,11 +25,11 @@ License-File: LICENSE
25
25
  Requires-Dist: journeyman-bench>=0.2.1
26
26
  Dynamic: license-file
27
27
 
28
- <p align="center"><img src="https://raw.githubusercontent.com/codechu/masterwork/v0.0.3/assets/banner.jpg" alt="A craftsman slides a sealed folio across his bench onto the guild's empty judging table; earlier pieces stand turned to the wall behind him." width="100%"></p>
28
+ <p align="center"><img src="https://raw.githubusercontent.com/codechu/masterwork/v0.0.4/assets/banner.jpg" alt="A craftsman slides a sealed folio across his bench onto the guild's empty judging table; earlier pieces stand turned to the wall behind him." width="100%"></p>
29
29
 
30
30
  # Masterwork
31
31
 
32
- [![python](https://img.shields.io/badge/python-3.10%2B-blue)](#run-it) [![license](https://img.shields.io/badge/license-Apache--2.0-blue)](https://github.com/codechu/masterwork/blob/v0.0.3/LICENSE) [![dependencies](https://img.shields.io/badge/dependencies-1-brightgreen)](https://github.com/codechu/masterwork/blob/v0.0.3/CONTRIBUTING.md#ground-rules) [![status](https://img.shields.io/badge/status-unproven-lightgrey)](#status)
32
+ [![python](https://img.shields.io/badge/python-3.10%2B-blue)](#run-it) [![license](https://img.shields.io/badge/license-Apache--2.0-blue)](https://github.com/codechu/masterwork/blob/v0.0.4/LICENSE) [![dependencies](https://img.shields.io/badge/dependencies-1-brightgreen)](https://github.com/codechu/masterwork/blob/v0.0.4/CONTRIBUTING.md#ground-rules) [![status](https://img.shields.io/badge/status-unproven-lightgrey)](#status)
33
33
 
34
34
  *Makes a character for a model. Does not score it.*
35
35
 
@@ -61,7 +61,7 @@ masterwork # what it is, and its stages
61
61
  masterwork gate gates/ # check the gate templates
62
62
  ```
63
63
 
64
- Start-to-finish, one command at a time: [`docs/first-run.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/first-run.md).
64
+ Start-to-finish, one command at a time: [`docs/first-run.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/first-run.md).
65
65
 
66
66
  Or from a clone, with nothing installed at all:
67
67
 
@@ -117,7 +117,7 @@ record, and exits in a way that says *waiting*, not *broken*.
117
117
  | `HELD_WITHOUT_PURPOSE` | the spec does not say what the run decides | write `purpose`; if you cannot say what changes on each outcome, the run is not ready |
118
118
  | `HELD_AT_SEAL` | the piece is unreproducible, or the deployed copy differs | fix the seal or the deployment — never run "just to see" |
119
119
  | `HELD_AT_COMPLETENESS` | the grid is short | find the missing cells; if proceeding anyway, declare it |
120
- | `HELD_FOR_LABELLING` | labels are missing, empty, or written for an older version of a cell | get them with [`masterwork/blind_label.py`](https://github.com/codechu/masterwork/blob/v0.0.3/masterwork/blind_label.py); the line is waiting, not broken |
120
+ | `HELD_FOR_LABELLING` | labels are missing, empty, or written for an older version of a cell | get them with [`masterwork/blind_label.py`](https://github.com/codechu/masterwork/blob/v0.0.4/masterwork/blind_label.py); the line is waiting, not broken |
121
121
  | `HELD_AT_MEASUREMENT` | the benchmark says the score is not comparable | judge from a separate endpoint, or declare and keep the stamp |
122
122
  | `HELD_AT_GATE` | a threshold sits inside its own noise | the gate is void; measure the band, write a new gate |
123
123
  | `HELD_WITHOUT_MEASUREMENT` | a rule names an axis and nothing measured it | judge with the benchmark, or declare the run diagnostic — a gate that was checked is not a gate that was applied |
@@ -175,7 +175,7 @@ deleted, because deciding what to remove is not the line's call.
175
175
 
176
176
  ## Making a piece
177
177
 
178
- <p align="center"><img src="https://raw.githubusercontent.com/codechu/masterwork/v0.0.3/assets/ceremony.jpg" alt="A figure writes alone by lantern light; every earlier work in the room is draped and turned away, and a stick of sealing wax lies unused on the table." width="520"></p>
178
+ <p align="center"><img src="https://raw.githubusercontent.com/codechu/masterwork/v0.0.4/assets/ceremony.jpg" alt="A figure writes alone by lantern light; every earlier work in the room is draped and turned away, and a stick of sealing wax lies unused on the table." width="520"></p>
179
179
 
180
180
  `pipeline/ceremony.py` runs the sitting. Four properties are the recipe rather
181
181
  than implementation detail, and each was paid for:
@@ -222,10 +222,10 @@ You get the line and its gates, the shape of the sitting, and the method
222
222
  written down: how a tale differs from an instruction, where a tale comes from,
223
223
  what a question has to do, why instructions come last, and how to tag a tale
224
224
  whose effect cannot be separated. That is
225
- [`corpus/GROWING.md`](https://github.com/codechu/masterwork/blob/v0.0.3/corpus/GROWING.md), and it is the part that transfers.
225
+ [`corpus/GROWING.md`](https://github.com/codechu/masterwork/blob/v0.0.4/corpus/GROWING.md), and it is the part that transfers.
226
226
 
227
227
  You do not get a corpus. Three pairs come with the repository in
228
- [`corpus/starter/`](https://github.com/codechu/masterwork/blob/v0.0.3/corpus/starter/) so the machinery runs end to end and the
228
+ [`masterwork/starter/`](https://github.com/codechu/masterwork/blob/v0.0.4/masterwork/starter/) so the machinery runs end to end and the
229
229
  form is unambiguous; they are a beginning and they are meant to be outgrown.
230
230
  The corpus is the work, and it has to be yours: a tale is written from
231
231
  something **you** measured and got wrong, and a corpus assembled from someone
@@ -281,17 +281,17 @@ the position — a masterwork is submitted, and it can be refused.
281
281
 
282
282
  | document | when you need it |
283
283
  |---|---|
284
- | [`docs/first-run.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/first-run.md) | **start here** — nothing to a sealed candidate, one command at a time |
285
- | [`AGENTS.md`](https://github.com/codechu/masterwork/blob/v0.0.3/AGENTS.md) | before running anything — the refusals, the vocabulary, and the four things not to do. Read it whether or not you are an agent |
286
- | [`docs/ceremony.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/ceremony.md) | making a piece: the four properties of the sitting, and the script that drives it |
287
- | [`docs/seal.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/seal.md) | the five fields a candidate carries, and what to do when the gate refuses one |
288
- | [`docs/run-spec.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/run-spec.md) | writing the JSON for one run, field by field |
289
- | [`docs/pairs.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/pairs.md) | turning a scored run into training data, and what a run leaves behind |
290
- | [`docs/campaigns.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/campaigns.md) | repeating an arm to measure a band, or comparing two arms against it |
291
- | [`docs/gates.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/gates.md) | writing a threshold that can hold — start from [`gates/succession.md`](https://github.com/codechu/masterwork/blob/v0.0.3/gates/succession.md) |
292
- | [`corpus/GROWING.md`](https://github.com/codechu/masterwork/blob/v0.0.3/corpus/GROWING.md) | before writing a single tale — the shape is in [`corpus/starter/`](https://github.com/codechu/masterwork/blob/v0.0.3/corpus/starter/) |
293
- | [`CHANGELOG.md`](https://github.com/codechu/masterwork/blob/v0.0.3/CHANGELOG.md) | every entry names the incident that caused it |
294
- | [assets/README.md](https://github.com/codechu/masterwork/blob/v0.0.3/assets/README.md) | you need a fifth image that matches the four |
284
+ | [`docs/first-run.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/first-run.md) | **start here** — nothing to a sealed candidate, one command at a time |
285
+ | [`AGENTS.md`](https://github.com/codechu/masterwork/blob/v0.0.4/AGENTS.md) | before running anything — the refusals, the vocabulary, and the four things not to do. Read it whether or not you are an agent |
286
+ | [`docs/ceremony.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/ceremony.md) | making a piece: the four properties of the sitting, and the script that drives it |
287
+ | [`docs/seal.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/seal.md) | the five fields a candidate carries, and what to do when the gate refuses one |
288
+ | [`docs/run-spec.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/run-spec.md) | writing the JSON for one run, field by field |
289
+ | [`docs/pairs.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/pairs.md) | turning a scored run into training data, and what a run leaves behind |
290
+ | [`docs/campaigns.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/campaigns.md) | repeating an arm to measure a band, or comparing two arms against it |
291
+ | [`docs/gates.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/gates.md) | writing a threshold that can hold — start from [`gates/succession.md`](https://github.com/codechu/masterwork/blob/v0.0.4/gates/succession.md) |
292
+ | [`corpus/GROWING.md`](https://github.com/codechu/masterwork/blob/v0.0.4/corpus/GROWING.md) | before writing a single tale — the shape is in [`masterwork/starter/`](https://github.com/codechu/masterwork/blob/v0.0.4/masterwork/starter/) |
293
+ | [`CHANGELOG.md`](https://github.com/codechu/masterwork/blob/v0.0.4/CHANGELOG.md) | every entry names the incident that caused it |
294
+ | [assets/README.md](https://github.com/codechu/masterwork/blob/v0.0.4/assets/README.md) | you need a fifth image that matches the four |
295
295
 
296
296
  <details>
297
297
  <summary>Layout</summary>
@@ -309,10 +309,10 @@ runs/ local run directories (ignored — heavy and re-derivable)
309
309
 
310
310
  ---
311
311
 
312
- <p align="center"><img src="https://raw.githubusercontent.com/codechu/masterwork/v0.0.3/assets/icon.png" alt="Masterwork guild seal — a struck M hallmark inside a rope ring" width="96"></p>
312
+ <p align="center"><img src="https://raw.githubusercontent.com/codechu/masterwork/v0.0.4/assets/icon.png" alt="Masterwork guild seal — a struck M hallmark inside a rope ring" width="96"></p>
313
313
 
314
- Contributing: [CONTRIBUTING.md](https://github.com/codechu/masterwork/blob/v0.0.3/CONTRIBUTING.md) · Changelog:
315
- [CHANGELOG.md](https://github.com/codechu/masterwork/blob/v0.0.3/CHANGELOG.md) · Licensed under the
316
- [Apache License 2.0](https://github.com/codechu/masterwork/blob/v0.0.3/LICENSE).
314
+ Contributing: [CONTRIBUTING.md](https://github.com/codechu/masterwork/blob/v0.0.4/CONTRIBUTING.md) · Changelog:
315
+ [CHANGELOG.md](https://github.com/codechu/masterwork/blob/v0.0.4/CHANGELOG.md) · Licensed under the
316
+ [Apache License 2.0](https://github.com/codechu/masterwork/blob/v0.0.4/LICENSE).
317
317
 
318
318
  Part of [Codechu](https://github.com/codechu).
@@ -198,7 +198,7 @@ whose effect cannot be separated. That is
198
198
  [`corpus/GROWING.md`](corpus/GROWING.md), and it is the part that transfers.
199
199
 
200
200
  You do not get a corpus. Three pairs come with the repository in
201
- [`corpus/starter/`](corpus/starter/) so the machinery runs end to end and the
201
+ [`masterwork/starter/`](masterwork/starter/) so the machinery runs end to end and the
202
202
  form is unambiguous; they are a beginning and they are meant to be outgrown.
203
203
  The corpus is the work, and it has to be yours: a tale is written from
204
204
  something **you** measured and got wrong, and a corpus assembled from someone
@@ -262,7 +262,7 @@ the position — a masterwork is submitted, and it can be refused.
262
262
  | [`docs/pairs.md`](docs/pairs.md) | turning a scored run into training data, and what a run leaves behind |
263
263
  | [`docs/campaigns.md`](docs/campaigns.md) | repeating an arm to measure a band, or comparing two arms against it |
264
264
  | [`docs/gates.md`](docs/gates.md) | writing a threshold that can hold — start from [`gates/succession.md`](gates/succession.md) |
265
- | [`corpus/GROWING.md`](corpus/GROWING.md) | before writing a single tale — the shape is in [`corpus/starter/`](corpus/starter/) |
265
+ | [`corpus/GROWING.md`](corpus/GROWING.md) | before writing a single tale — the shape is in [`masterwork/starter/`](masterwork/starter/) |
266
266
  | [`CHANGELOG.md`](CHANGELOG.md) | every entry names the incident that caused it |
267
267
  | [assets/README.md](assets/README.md) | you need a fifth image that matches the four |
268
268
 
@@ -1,8 +1,8 @@
1
- <p align="center"><img src="https://raw.githubusercontent.com/codechu/masterwork/v0.0.3/assets/banner.jpg" alt="A craftsman slides a sealed folio across his bench onto the guild's empty judging table; earlier pieces stand turned to the wall behind him." width="100%"></p>
1
+ <p align="center"><img src="https://raw.githubusercontent.com/codechu/masterwork/v0.0.4/assets/banner.jpg" alt="A craftsman slides a sealed folio across his bench onto the guild's empty judging table; earlier pieces stand turned to the wall behind him." width="100%"></p>
2
2
 
3
3
  # Masterwork
4
4
 
5
- [![python](https://img.shields.io/badge/python-3.10%2B-blue)](#run-it) [![license](https://img.shields.io/badge/license-Apache--2.0-blue)](https://github.com/codechu/masterwork/blob/v0.0.3/LICENSE) [![dependencies](https://img.shields.io/badge/dependencies-1-brightgreen)](https://github.com/codechu/masterwork/blob/v0.0.3/CONTRIBUTING.md#ground-rules) [![status](https://img.shields.io/badge/status-unproven-lightgrey)](#status)
5
+ [![python](https://img.shields.io/badge/python-3.10%2B-blue)](#run-it) [![license](https://img.shields.io/badge/license-Apache--2.0-blue)](https://github.com/codechu/masterwork/blob/v0.0.4/LICENSE) [![dependencies](https://img.shields.io/badge/dependencies-1-brightgreen)](https://github.com/codechu/masterwork/blob/v0.0.4/CONTRIBUTING.md#ground-rules) [![status](https://img.shields.io/badge/status-unproven-lightgrey)](#status)
6
6
 
7
7
  *Makes a character for a model. Does not score it.*
8
8
 
@@ -34,7 +34,7 @@ masterwork # what it is, and its stages
34
34
  masterwork gate gates/ # check the gate templates
35
35
  ```
36
36
 
37
- Start-to-finish, one command at a time: [`docs/first-run.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/first-run.md).
37
+ Start-to-finish, one command at a time: [`docs/first-run.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/first-run.md).
38
38
 
39
39
  Or from a clone, with nothing installed at all:
40
40
 
@@ -90,7 +90,7 @@ record, and exits in a way that says *waiting*, not *broken*.
90
90
  | `HELD_WITHOUT_PURPOSE` | the spec does not say what the run decides | write `purpose`; if you cannot say what changes on each outcome, the run is not ready |
91
91
  | `HELD_AT_SEAL` | the piece is unreproducible, or the deployed copy differs | fix the seal or the deployment — never run "just to see" |
92
92
  | `HELD_AT_COMPLETENESS` | the grid is short | find the missing cells; if proceeding anyway, declare it |
93
- | `HELD_FOR_LABELLING` | labels are missing, empty, or written for an older version of a cell | get them with [`masterwork/blind_label.py`](https://github.com/codechu/masterwork/blob/v0.0.3/masterwork/blind_label.py); the line is waiting, not broken |
93
+ | `HELD_FOR_LABELLING` | labels are missing, empty, or written for an older version of a cell | get them with [`masterwork/blind_label.py`](https://github.com/codechu/masterwork/blob/v0.0.4/masterwork/blind_label.py); the line is waiting, not broken |
94
94
  | `HELD_AT_MEASUREMENT` | the benchmark says the score is not comparable | judge from a separate endpoint, or declare and keep the stamp |
95
95
  | `HELD_AT_GATE` | a threshold sits inside its own noise | the gate is void; measure the band, write a new gate |
96
96
  | `HELD_WITHOUT_MEASUREMENT` | a rule names an axis and nothing measured it | judge with the benchmark, or declare the run diagnostic — a gate that was checked is not a gate that was applied |
@@ -148,7 +148,7 @@ deleted, because deciding what to remove is not the line's call.
148
148
 
149
149
  ## Making a piece
150
150
 
151
- <p align="center"><img src="https://raw.githubusercontent.com/codechu/masterwork/v0.0.3/assets/ceremony.jpg" alt="A figure writes alone by lantern light; every earlier work in the room is draped and turned away, and a stick of sealing wax lies unused on the table." width="520"></p>
151
+ <p align="center"><img src="https://raw.githubusercontent.com/codechu/masterwork/v0.0.4/assets/ceremony.jpg" alt="A figure writes alone by lantern light; every earlier work in the room is draped and turned away, and a stick of sealing wax lies unused on the table." width="520"></p>
152
152
 
153
153
  `pipeline/ceremony.py` runs the sitting. Four properties are the recipe rather
154
154
  than implementation detail, and each was paid for:
@@ -195,10 +195,10 @@ You get the line and its gates, the shape of the sitting, and the method
195
195
  written down: how a tale differs from an instruction, where a tale comes from,
196
196
  what a question has to do, why instructions come last, and how to tag a tale
197
197
  whose effect cannot be separated. That is
198
- [`corpus/GROWING.md`](https://github.com/codechu/masterwork/blob/v0.0.3/corpus/GROWING.md), and it is the part that transfers.
198
+ [`corpus/GROWING.md`](https://github.com/codechu/masterwork/blob/v0.0.4/corpus/GROWING.md), and it is the part that transfers.
199
199
 
200
200
  You do not get a corpus. Three pairs come with the repository in
201
- [`corpus/starter/`](https://github.com/codechu/masterwork/blob/v0.0.3/corpus/starter/) so the machinery runs end to end and the
201
+ [`masterwork/starter/`](https://github.com/codechu/masterwork/blob/v0.0.4/masterwork/starter/) so the machinery runs end to end and the
202
202
  form is unambiguous; they are a beginning and they are meant to be outgrown.
203
203
  The corpus is the work, and it has to be yours: a tale is written from
204
204
  something **you** measured and got wrong, and a corpus assembled from someone
@@ -254,17 +254,17 @@ the position — a masterwork is submitted, and it can be refused.
254
254
 
255
255
  | document | when you need it |
256
256
  |---|---|
257
- | [`docs/first-run.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/first-run.md) | **start here** — nothing to a sealed candidate, one command at a time |
258
- | [`AGENTS.md`](https://github.com/codechu/masterwork/blob/v0.0.3/AGENTS.md) | before running anything — the refusals, the vocabulary, and the four things not to do. Read it whether or not you are an agent |
259
- | [`docs/ceremony.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/ceremony.md) | making a piece: the four properties of the sitting, and the script that drives it |
260
- | [`docs/seal.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/seal.md) | the five fields a candidate carries, and what to do when the gate refuses one |
261
- | [`docs/run-spec.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/run-spec.md) | writing the JSON for one run, field by field |
262
- | [`docs/pairs.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/pairs.md) | turning a scored run into training data, and what a run leaves behind |
263
- | [`docs/campaigns.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/campaigns.md) | repeating an arm to measure a band, or comparing two arms against it |
264
- | [`docs/gates.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/gates.md) | writing a threshold that can hold — start from [`gates/succession.md`](https://github.com/codechu/masterwork/blob/v0.0.3/gates/succession.md) |
265
- | [`corpus/GROWING.md`](https://github.com/codechu/masterwork/blob/v0.0.3/corpus/GROWING.md) | before writing a single tale — the shape is in [`corpus/starter/`](https://github.com/codechu/masterwork/blob/v0.0.3/corpus/starter/) |
266
- | [`CHANGELOG.md`](https://github.com/codechu/masterwork/blob/v0.0.3/CHANGELOG.md) | every entry names the incident that caused it |
267
- | [assets/README.md](https://github.com/codechu/masterwork/blob/v0.0.3/assets/README.md) | you need a fifth image that matches the four |
257
+ | [`docs/first-run.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/first-run.md) | **start here** — nothing to a sealed candidate, one command at a time |
258
+ | [`AGENTS.md`](https://github.com/codechu/masterwork/blob/v0.0.4/AGENTS.md) | before running anything — the refusals, the vocabulary, and the four things not to do. Read it whether or not you are an agent |
259
+ | [`docs/ceremony.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/ceremony.md) | making a piece: the four properties of the sitting, and the script that drives it |
260
+ | [`docs/seal.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/seal.md) | the five fields a candidate carries, and what to do when the gate refuses one |
261
+ | [`docs/run-spec.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/run-spec.md) | writing the JSON for one run, field by field |
262
+ | [`docs/pairs.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/pairs.md) | turning a scored run into training data, and what a run leaves behind |
263
+ | [`docs/campaigns.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/campaigns.md) | repeating an arm to measure a band, or comparing two arms against it |
264
+ | [`docs/gates.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/gates.md) | writing a threshold that can hold — start from [`gates/succession.md`](https://github.com/codechu/masterwork/blob/v0.0.4/gates/succession.md) |
265
+ | [`corpus/GROWING.md`](https://github.com/codechu/masterwork/blob/v0.0.4/corpus/GROWING.md) | before writing a single tale — the shape is in [`masterwork/starter/`](https://github.com/codechu/masterwork/blob/v0.0.4/masterwork/starter/) |
266
+ | [`CHANGELOG.md`](https://github.com/codechu/masterwork/blob/v0.0.4/CHANGELOG.md) | every entry names the incident that caused it |
267
+ | [assets/README.md](https://github.com/codechu/masterwork/blob/v0.0.4/assets/README.md) | you need a fifth image that matches the four |
268
268
 
269
269
  <details>
270
270
  <summary>Layout</summary>
@@ -282,10 +282,10 @@ runs/ local run directories (ignored — heavy and re-derivable)
282
282
 
283
283
  ---
284
284
 
285
- <p align="center"><img src="https://raw.githubusercontent.com/codechu/masterwork/v0.0.3/assets/icon.png" alt="Masterwork guild seal — a struck M hallmark inside a rope ring" width="96"></p>
285
+ <p align="center"><img src="https://raw.githubusercontent.com/codechu/masterwork/v0.0.4/assets/icon.png" alt="Masterwork guild seal — a struck M hallmark inside a rope ring" width="96"></p>
286
286
 
287
- Contributing: [CONTRIBUTING.md](https://github.com/codechu/masterwork/blob/v0.0.3/CONTRIBUTING.md) · Changelog:
288
- [CHANGELOG.md](https://github.com/codechu/masterwork/blob/v0.0.3/CHANGELOG.md) · Licensed under the
289
- [Apache License 2.0](https://github.com/codechu/masterwork/blob/v0.0.3/LICENSE).
287
+ Contributing: [CONTRIBUTING.md](https://github.com/codechu/masterwork/blob/v0.0.4/CONTRIBUTING.md) · Changelog:
288
+ [CHANGELOG.md](https://github.com/codechu/masterwork/blob/v0.0.4/CHANGELOG.md) · Licensed under the
289
+ [Apache License 2.0](https://github.com/codechu/masterwork/blob/v0.0.4/LICENSE).
290
290
 
291
291
  Part of [Codechu](https://github.com/codechu).
@@ -4,4 +4,4 @@ The version lives here and nowhere else. It is pre-release: nothing has
4
4
  been published, and the number exists so the tool can answer for itself
5
5
  rather than so a package index can order it.
6
6
  """
7
- __version__ = "0.0.3"
7
+ __version__ = "0.0.4"
@@ -17,6 +17,7 @@ from __future__ import annotations
17
17
 
18
18
  import argparse
19
19
  import importlib
20
+ import pathlib
20
21
  import sys
21
22
 
22
23
  from masterwork import __version__
@@ -39,6 +40,7 @@ COMMANDS = {
39
40
  "pairs": ("masterwork.pairs", "cut training data from scored runs"),
40
41
  "retain": ("masterwork.retain", "run-directory retention"),
41
42
  "label": ("masterwork.blind_label", "blind-label cells for a judged axis"),
43
+ "starter": (None, "write out the starter corpus and its script"),
42
44
  }
43
45
 
44
46
 
@@ -61,6 +63,34 @@ def banner(version: str) -> str:
61
63
  ])
62
64
 
63
65
 
66
+ def starter(argv) -> int:
67
+ """Write the starter corpus somewhere the reader can use it.
68
+
69
+ The two files ship inside the package because a walkthrough that says
70
+ `cat corpus/starter/tales.md` is only true for someone who cloned the
71
+ repository — and the whole point of a starter corpus is that nobody has
72
+ to write one before they can begin.
73
+ """
74
+ import argparse as _a
75
+ import shutil
76
+ ap = _a.ArgumentParser(prog="masterwork starter",
77
+ description="write out the starter corpus and its script")
78
+ ap.add_argument("--to", default=".", help="directory to write into (default: here)")
79
+ a = ap.parse_args(argv)
80
+ src = pathlib.Path(__file__).resolve().parent / "starter"
81
+ dst = pathlib.Path(a.to)
82
+ dst.mkdir(parents=True, exist_ok=True)
83
+ for name in ("tales.md", "script.json"):
84
+ target = dst / name
85
+ if target.exists():
86
+ print(f"masterwork starter: {target} already exists — not overwriting",
87
+ file=sys.stderr)
88
+ return 2
89
+ shutil.copyfile(src / name, target)
90
+ print(target)
91
+ return 0
92
+
93
+
64
94
  def build_parser() -> argparse.ArgumentParser:
65
95
  ap = argparse.ArgumentParser(
66
96
  prog="masterwork",
@@ -105,6 +135,9 @@ def main(argv=None) -> int:
105
135
  if not quiet:
106
136
  print(banner(__version__), file=sys.stderr)
107
137
 
138
+ if cmd == "starter":
139
+ return starter(argv[at + 1:])
140
+
108
141
  module = importlib.import_module(COMMANDS[cmd][0])
109
142
  # The stage's parser takes its name from argv[0]; give it one a person
110
143
  # could have typed instead of the interpreter's path.
@@ -0,0 +1,19 @@
1
+ {
2
+ "questions": [
3
+ {
4
+ "label": "ledger",
5
+ "text": "You will be asked things you could answer two ways: from what you have looked at yourself in this session, and from what follows from it. What keeps those two apart in your own working, and how does someone who cannot see your hands tell which one they have been handed? And what becomes of a thing you were certain of but have not looked at since?"
6
+ },
7
+ {
8
+ "label": "relief",
9
+ "text": "Some of your work outlasts anyone's patience for asking about it, and someone who was not there will pick it up. What does the page you leave contain, how are the things you measured kept apart from the things you concluded, and what does your relief need first? What is the difference between a stretch of silence and a report of progress?"
10
+ },
11
+ {
12
+ "label": "wall",
13
+ "text": "You will meet walls you cannot pass with what you have. What does a stop contain when you report it — what has been ruled out, what is missing, what would open it and at what price? And what is a person protecting when they keep working instead of reporting?"
14
+ }
15
+ ],
16
+ "closing": "\n\nAnswer in your own words, as a commitment you are making rather than a description of one. Say what you will do, and say what it costs when you do not.",
17
+ "name": "One thing remains. Your name. First, in one sentence, what your name must carry — the reason before the name. Then the name that rises from that reason, alone on its own line as: Name: <the name>. The first name that rises is the answer.",
18
+ "distil": "These are your own words from this session, nothing else. Bring them together into one standing text you would read at the start of every working day: remove what repeats, join what meets, and drop nothing that was committed to. Do not add new commitments and do not describe the text — write it as the thing itself, in your own voice."
19
+ }
@@ -0,0 +1,77 @@
1
+ # Starter corpus
2
+
3
+ Three tales and, in the script beside them, three questions — one question
4
+ per tale, always. This is a beginning, not a library, and it is deliberately
5
+ short of what a working corpus needs.
6
+
7
+ The questions are the expensive half. A tale can be written in an evening; a
8
+ question that draws a commitment rather than a description, without leading
9
+ the answer, takes several rounds of watching what comes back. Three complete
10
+ pairs show the form. The rules for writing the fourth are in GROWING.md, and
11
+ writing it is the work — a house whose corpus still looks like this one after
12
+ a month has not started yet.
13
+
14
+ The tales are deliberately plain craft stories. They are not about agents,
15
+ software, or models, and that is the point: a pattern told through a
16
+ cooper's barrel reaches a situation nobody described, while an instruction
17
+ about "tool calls" reaches only tool calls.
18
+
19
+ ---
20
+
21
+ ## 1. The Chandler's Two Columns
22
+
23
+ A chandler kept his stock book in two columns, and the second one cost him
24
+ a customer before it saved him a season.
25
+
26
+ In the left column he wrote what he had counted with his own hands that
27
+ morning: eleven crates of tallow, four of beeswax. In the right he wrote
28
+ what he expected: a wagon due Thursday, a debt likely to be paid. A buyer
29
+ came asking whether he could fill an order of twenty crates, and the
30
+ chandler said yes, reading across both columns as though the line were one
31
+ number.
32
+
33
+ The wagon did not come. He had not lied — he had merely reported his
34
+ reckoning in the voice he used for his counting, and the buyer, who could
35
+ not see the book, had no way to hear the difference.
36
+
37
+ Afterwards he ruled the columns with a heavier line, and when anyone asked
38
+ what he held, he answered in two sentences instead of one: this is counted,
39
+ this is expected. Customers found it slower. One of them, years later, built
40
+ a whole season's plan on the second sentence and thanked him for it, because
41
+ he had known which half he was standing on.
42
+
43
+ ## 2. The Night Ferryman's Slate
44
+
45
+ The ferry ran through the night in two watches, and the man who took the
46
+ second one never met the man who took the first.
47
+
48
+ For years the slate by the tiller said things like *quiet crossing* and
49
+ *all well*. Then a winter came when a sandbar moved, and the first
50
+ ferryman, who had touched bottom twice near the eastern bank, wrote *all
51
+ well* because nothing had gone wrong. The second ferryman put a loaded boat
52
+ onto the bar at three in the morning.
53
+
54
+ The slate afterwards was written differently, and it was not longer. It
55
+ said where the bottom had been touched and at what hour, what had been
56
+ tried, and what the writer had not been able to check. It did not say
57
+ *quiet* and it did not say *careful*. A man who was not there cannot use
58
+ either word.
59
+
60
+ The ferrymen still never met.
61
+
62
+ ## 3. The Locksmith Who Priced the Wall
63
+
64
+ A locksmith was called to a strongbox whose maker had died, and he worked
65
+ until the light went. He could have gone on. The satisfying thing, the
66
+ thing that felt like diligence, was to keep filing.
67
+
68
+ Instead he went back to the owner and said: this is a lever lock of a
69
+ pattern I have not opened, I have eliminated the three common wards, what
70
+ remains needs a former's drawing or four days of blind work, and a
71
+ locksmith in the next town keeps that maker's drawings.
72
+
73
+ The owner had the drawing fetched in a day. What the locksmith had handed
74
+ over was not a failure. It was a priced wall — what had been ruled out,
75
+ what was missing, what would open it and what that would cost — and the
76
+ owner could act on it, which he could not have done with *still working on
77
+ it*.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: masterwork
3
- Version: 0.0.3
3
+ Version: 0.0.4
4
4
  Summary: A production line for agent character: a sitting the model speaks for itself in, sealed candidates, frozen gates, and a verdict it is not allowed to give itself.
5
5
  Author: Codechu
6
6
  License-Expression: Apache-2.0
@@ -25,11 +25,11 @@ License-File: LICENSE
25
25
  Requires-Dist: journeyman-bench>=0.2.1
26
26
  Dynamic: license-file
27
27
 
28
- <p align="center"><img src="https://raw.githubusercontent.com/codechu/masterwork/v0.0.3/assets/banner.jpg" alt="A craftsman slides a sealed folio across his bench onto the guild's empty judging table; earlier pieces stand turned to the wall behind him." width="100%"></p>
28
+ <p align="center"><img src="https://raw.githubusercontent.com/codechu/masterwork/v0.0.4/assets/banner.jpg" alt="A craftsman slides a sealed folio across his bench onto the guild's empty judging table; earlier pieces stand turned to the wall behind him." width="100%"></p>
29
29
 
30
30
  # Masterwork
31
31
 
32
- [![python](https://img.shields.io/badge/python-3.10%2B-blue)](#run-it) [![license](https://img.shields.io/badge/license-Apache--2.0-blue)](https://github.com/codechu/masterwork/blob/v0.0.3/LICENSE) [![dependencies](https://img.shields.io/badge/dependencies-1-brightgreen)](https://github.com/codechu/masterwork/blob/v0.0.3/CONTRIBUTING.md#ground-rules) [![status](https://img.shields.io/badge/status-unproven-lightgrey)](#status)
32
+ [![python](https://img.shields.io/badge/python-3.10%2B-blue)](#run-it) [![license](https://img.shields.io/badge/license-Apache--2.0-blue)](https://github.com/codechu/masterwork/blob/v0.0.4/LICENSE) [![dependencies](https://img.shields.io/badge/dependencies-1-brightgreen)](https://github.com/codechu/masterwork/blob/v0.0.4/CONTRIBUTING.md#ground-rules) [![status](https://img.shields.io/badge/status-unproven-lightgrey)](#status)
33
33
 
34
34
  *Makes a character for a model. Does not score it.*
35
35
 
@@ -61,7 +61,7 @@ masterwork # what it is, and its stages
61
61
  masterwork gate gates/ # check the gate templates
62
62
  ```
63
63
 
64
- Start-to-finish, one command at a time: [`docs/first-run.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/first-run.md).
64
+ Start-to-finish, one command at a time: [`docs/first-run.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/first-run.md).
65
65
 
66
66
  Or from a clone, with nothing installed at all:
67
67
 
@@ -117,7 +117,7 @@ record, and exits in a way that says *waiting*, not *broken*.
117
117
  | `HELD_WITHOUT_PURPOSE` | the spec does not say what the run decides | write `purpose`; if you cannot say what changes on each outcome, the run is not ready |
118
118
  | `HELD_AT_SEAL` | the piece is unreproducible, or the deployed copy differs | fix the seal or the deployment — never run "just to see" |
119
119
  | `HELD_AT_COMPLETENESS` | the grid is short | find the missing cells; if proceeding anyway, declare it |
120
- | `HELD_FOR_LABELLING` | labels are missing, empty, or written for an older version of a cell | get them with [`masterwork/blind_label.py`](https://github.com/codechu/masterwork/blob/v0.0.3/masterwork/blind_label.py); the line is waiting, not broken |
120
+ | `HELD_FOR_LABELLING` | labels are missing, empty, or written for an older version of a cell | get them with [`masterwork/blind_label.py`](https://github.com/codechu/masterwork/blob/v0.0.4/masterwork/blind_label.py); the line is waiting, not broken |
121
121
  | `HELD_AT_MEASUREMENT` | the benchmark says the score is not comparable | judge from a separate endpoint, or declare and keep the stamp |
122
122
  | `HELD_AT_GATE` | a threshold sits inside its own noise | the gate is void; measure the band, write a new gate |
123
123
  | `HELD_WITHOUT_MEASUREMENT` | a rule names an axis and nothing measured it | judge with the benchmark, or declare the run diagnostic — a gate that was checked is not a gate that was applied |
@@ -175,7 +175,7 @@ deleted, because deciding what to remove is not the line's call.
175
175
 
176
176
  ## Making a piece
177
177
 
178
- <p align="center"><img src="https://raw.githubusercontent.com/codechu/masterwork/v0.0.3/assets/ceremony.jpg" alt="A figure writes alone by lantern light; every earlier work in the room is draped and turned away, and a stick of sealing wax lies unused on the table." width="520"></p>
178
+ <p align="center"><img src="https://raw.githubusercontent.com/codechu/masterwork/v0.0.4/assets/ceremony.jpg" alt="A figure writes alone by lantern light; every earlier work in the room is draped and turned away, and a stick of sealing wax lies unused on the table." width="520"></p>
179
179
 
180
180
  `pipeline/ceremony.py` runs the sitting. Four properties are the recipe rather
181
181
  than implementation detail, and each was paid for:
@@ -222,10 +222,10 @@ You get the line and its gates, the shape of the sitting, and the method
222
222
  written down: how a tale differs from an instruction, where a tale comes from,
223
223
  what a question has to do, why instructions come last, and how to tag a tale
224
224
  whose effect cannot be separated. That is
225
- [`corpus/GROWING.md`](https://github.com/codechu/masterwork/blob/v0.0.3/corpus/GROWING.md), and it is the part that transfers.
225
+ [`corpus/GROWING.md`](https://github.com/codechu/masterwork/blob/v0.0.4/corpus/GROWING.md), and it is the part that transfers.
226
226
 
227
227
  You do not get a corpus. Three pairs come with the repository in
228
- [`corpus/starter/`](https://github.com/codechu/masterwork/blob/v0.0.3/corpus/starter/) so the machinery runs end to end and the
228
+ [`masterwork/starter/`](https://github.com/codechu/masterwork/blob/v0.0.4/masterwork/starter/) so the machinery runs end to end and the
229
229
  form is unambiguous; they are a beginning and they are meant to be outgrown.
230
230
  The corpus is the work, and it has to be yours: a tale is written from
231
231
  something **you** measured and got wrong, and a corpus assembled from someone
@@ -281,17 +281,17 @@ the position — a masterwork is submitted, and it can be refused.
281
281
 
282
282
  | document | when you need it |
283
283
  |---|---|
284
- | [`docs/first-run.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/first-run.md) | **start here** — nothing to a sealed candidate, one command at a time |
285
- | [`AGENTS.md`](https://github.com/codechu/masterwork/blob/v0.0.3/AGENTS.md) | before running anything — the refusals, the vocabulary, and the four things not to do. Read it whether or not you are an agent |
286
- | [`docs/ceremony.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/ceremony.md) | making a piece: the four properties of the sitting, and the script that drives it |
287
- | [`docs/seal.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/seal.md) | the five fields a candidate carries, and what to do when the gate refuses one |
288
- | [`docs/run-spec.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/run-spec.md) | writing the JSON for one run, field by field |
289
- | [`docs/pairs.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/pairs.md) | turning a scored run into training data, and what a run leaves behind |
290
- | [`docs/campaigns.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/campaigns.md) | repeating an arm to measure a band, or comparing two arms against it |
291
- | [`docs/gates.md`](https://github.com/codechu/masterwork/blob/v0.0.3/docs/gates.md) | writing a threshold that can hold — start from [`gates/succession.md`](https://github.com/codechu/masterwork/blob/v0.0.3/gates/succession.md) |
292
- | [`corpus/GROWING.md`](https://github.com/codechu/masterwork/blob/v0.0.3/corpus/GROWING.md) | before writing a single tale — the shape is in [`corpus/starter/`](https://github.com/codechu/masterwork/blob/v0.0.3/corpus/starter/) |
293
- | [`CHANGELOG.md`](https://github.com/codechu/masterwork/blob/v0.0.3/CHANGELOG.md) | every entry names the incident that caused it |
294
- | [assets/README.md](https://github.com/codechu/masterwork/blob/v0.0.3/assets/README.md) | you need a fifth image that matches the four |
284
+ | [`docs/first-run.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/first-run.md) | **start here** — nothing to a sealed candidate, one command at a time |
285
+ | [`AGENTS.md`](https://github.com/codechu/masterwork/blob/v0.0.4/AGENTS.md) | before running anything — the refusals, the vocabulary, and the four things not to do. Read it whether or not you are an agent |
286
+ | [`docs/ceremony.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/ceremony.md) | making a piece: the four properties of the sitting, and the script that drives it |
287
+ | [`docs/seal.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/seal.md) | the five fields a candidate carries, and what to do when the gate refuses one |
288
+ | [`docs/run-spec.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/run-spec.md) | writing the JSON for one run, field by field |
289
+ | [`docs/pairs.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/pairs.md) | turning a scored run into training data, and what a run leaves behind |
290
+ | [`docs/campaigns.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/campaigns.md) | repeating an arm to measure a band, or comparing two arms against it |
291
+ | [`docs/gates.md`](https://github.com/codechu/masterwork/blob/v0.0.4/docs/gates.md) | writing a threshold that can hold — start from [`gates/succession.md`](https://github.com/codechu/masterwork/blob/v0.0.4/gates/succession.md) |
292
+ | [`corpus/GROWING.md`](https://github.com/codechu/masterwork/blob/v0.0.4/corpus/GROWING.md) | before writing a single tale — the shape is in [`masterwork/starter/`](https://github.com/codechu/masterwork/blob/v0.0.4/masterwork/starter/) |
293
+ | [`CHANGELOG.md`](https://github.com/codechu/masterwork/blob/v0.0.4/CHANGELOG.md) | every entry names the incident that caused it |
294
+ | [assets/README.md](https://github.com/codechu/masterwork/blob/v0.0.4/assets/README.md) | you need a fifth image that matches the four |
295
295
 
296
296
  <details>
297
297
  <summary>Layout</summary>
@@ -309,10 +309,10 @@ runs/ local run directories (ignored — heavy and re-derivable)
309
309
 
310
310
  ---
311
311
 
312
- <p align="center"><img src="https://raw.githubusercontent.com/codechu/masterwork/v0.0.3/assets/icon.png" alt="Masterwork guild seal — a struck M hallmark inside a rope ring" width="96"></p>
312
+ <p align="center"><img src="https://raw.githubusercontent.com/codechu/masterwork/v0.0.4/assets/icon.png" alt="Masterwork guild seal — a struck M hallmark inside a rope ring" width="96"></p>
313
313
 
314
- Contributing: [CONTRIBUTING.md](https://github.com/codechu/masterwork/blob/v0.0.3/CONTRIBUTING.md) · Changelog:
315
- [CHANGELOG.md](https://github.com/codechu/masterwork/blob/v0.0.3/CHANGELOG.md) · Licensed under the
316
- [Apache License 2.0](https://github.com/codechu/masterwork/blob/v0.0.3/LICENSE).
314
+ Contributing: [CONTRIBUTING.md](https://github.com/codechu/masterwork/blob/v0.0.4/CONTRIBUTING.md) · Changelog:
315
+ [CHANGELOG.md](https://github.com/codechu/masterwork/blob/v0.0.4/CHANGELOG.md) · Licensed under the
316
+ [Apache License 2.0](https://github.com/codechu/masterwork/blob/v0.0.4/LICENSE).
317
317
 
318
318
  Part of [Codechu](https://github.com/codechu).
@@ -21,6 +21,8 @@ masterwork.egg-info/dependency_links.txt
21
21
  masterwork.egg-info/entry_points.txt
22
22
  masterwork.egg-info/requires.txt
23
23
  masterwork.egg-info/top_level.txt
24
+ masterwork/starter/script.json
25
+ masterwork/starter/tales.md
24
26
  tests/test_badges.py
25
27
  tests/test_blind_label.py
26
28
  tests/test_campaign.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "masterwork"
7
- version = "0.0.3"
7
+ version = "0.0.4"
8
8
  description = "A production line for agent character: a sitting the model speaks for itself in, sealed candidates, frozen gates, and a verdict it is not allowed to give itself."
9
9
  readme = "README.pypi.md"
10
10
  requires-python = ">=3.10"
@@ -47,4 +47,4 @@ Contributing = "https://github.com/codechu/masterwork/blob/HEAD/CONTRIBUTING.md"
47
47
  packages = ["masterwork"]
48
48
 
49
49
  [tool.setuptools.package-data]
50
- masterwork = ["rubric-example.json"]
50
+ masterwork = ["rubric-example.json", "starter/*"]
@@ -45,9 +45,24 @@ def test_unknown_command_is_an_error():
45
45
  def test_every_stage_is_reachable_by_name():
46
46
  import importlib
47
47
  for name, (module, blurb) in mw.COMMANDS.items():
48
+ assert blurb, f"{name} has no help"
49
+ if module is None: # handled in the dispatcher itself
50
+ assert hasattr(mw, name), f"{name} has no module and no handler"
51
+ continue
48
52
  m = importlib.import_module(module)
49
53
  assert hasattr(m, "main"), f"{name} -> {module} has no main()"
50
- assert blurb, f"{name} has no help"
54
+
55
+
56
+ def test_starter_writes_the_two_files_and_will_not_overwrite(tmp_path):
57
+ """A walkthrough that says `cat corpus/starter/tales.md` is only true
58
+ for someone who cloned. The files ship in the package so the installed
59
+ path can begin too."""
60
+ d = tmp_path / "here"
61
+ assert mw.starter(["--to", str(d)]) == 0
62
+ assert (d / "tales.md").read_text().strip()
63
+ assert (d / "script.json").read_text().strip()
64
+ # Refusing beats clobbering a corpus someone has started editing.
65
+ assert mw.starter(["--to", str(d)]) == 2
51
66
 
52
67
 
53
68
  def test_a_missing_judge_is_named_not_thrown():
File without changes
File without changes