frontface-proofit 1.0.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,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ryan Wesley Hitchcock
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,163 @@
1
+ Metadata-Version: 2.4
2
+ Name: frontface-proofit
3
+ Version: 1.0.0
4
+ Summary: Fail-closed linter for locked-down runbooks: ten rules of workflow discipline as code
5
+ Author: Ryan Wesley Hitchcock
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/ohpersonperson/frontface
8
+ Keywords: linter,runbook,workflow,technical-writing,validation
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.10
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Dynamic: license-file
16
+
17
+ # proofit — fail-closed linter for locked-down runbooks
18
+
19
+ A runbook is a step-by-step procedure written so tightly that two different
20
+ people following it do the same thing and get the same result. proofit checks
21
+ a runbook draft against ten rules of workflow discipline — and **rejects the
22
+ draft if any rule is violated**. No warnings, no advisories. Fail-closed:
23
+ exit 1 until it's fixed, exit 0 when it's locked down.
24
+
25
+ It checks the runbook's **shape, not its truth**: it can tell you a step is
26
+ missing its verification block, not whether the verification would actually
27
+ work. A fully-specified unwise workflow passes; a wise but sloppy one doesn't.
28
+ That distinction is the whole product — see the FAQ.
29
+
30
+ No prerequisites. You don't need to know anything about this project's
31
+ history or any framework. The mechanism is the whole product.
32
+
33
+ *(Lineage: this is the front-facing conversion of the `proofit` skill from
34
+ Ryan's skill-suite, MIT. What changed in the conversion is documented in
35
+ CHANGELOG.md.)*
36
+
37
+ ## What it does
38
+
39
+ You write the runbook as Markdown in the template shape
40
+ (`templates/runbook-template.md` — or print it with `python -m proofit
41
+ template`):
42
+
43
+ - **Ground Rules & Prerequisites** — baseline, routing specs per service,
44
+ tools/items, expected outcome
45
+ - **Step-by-Step Directives** — numbered steps, each with **Do:** /
46
+ **Look for:** / **Verify:** / **If wrong:** / **Fix:**
47
+ - **Validation & Closure** — success condition plus consistency checkpoints
48
+
49
+ The linter parses that shape and runs ten checks:
50
+
51
+ | # | Rule | How it's checked |
52
+ |---|------|------------------|
53
+ | 1 | Remove every assumption | Heuristic: flags bare unlabeled directives ("Press Continue") and claims of automatic behavior ("is done automatically"). Narrow by design — see below. |
54
+ | 2 | All prerequisites upfront | Structure: the section must exist before step 1 and cover all eight fields (hardware, software, accounts, permissions, files, internet access, free-tier limits, starting state). |
55
+ | 3 | One action per step | Structure: each `Do:` holds exactly one verb-led action; steps numbered 1..N. |
56
+ | 4 | Concrete references | Flags bare UI nouns ("the button") and vague references ("open the file") with no visible label. Qualified nouns ("a confirmation dialog") don't fire. |
57
+ | 5 | Explain technical terms | Convention: where a glossary exists, every entry must match `Term (definition)`. Detecting undefined jargon *without* a glossary is out of scope — stated, not pretended. |
58
+ | 6 | Verification after every milestone | Structure: every step ends with a `Verify:` block in observable language ("displays", "exists", "contains"). |
59
+ | 7 | Immediate recovery | Structure: every step carries `If wrong:` + `Fix:`. |
60
+ | 8 | Never skip state changes | Heuristic: a `Do:` starting with a state-changing verb (open, close, install, …) must describe the resulting state in transition language ("a dialog appears"). Narrow by design. |
61
+ | 9 | Routing decisions upfront | Schema: per named service — when to use, free-tier limits, verbatim prompt, expected output format — plus rate-limit handling and error paths. |
62
+ | 10 | Finish with full validation | Structure: the document ends with Validation & Closure (never a step), with a success condition and a checklist. |
63
+
64
+ ## Why it works
65
+
66
+ Most workflow failures are specification failures, not execution failures.
67
+ Someone improvises mid-stream because the routing decision was never written
68
+ down. Someone skips a prerequisite because it was revealed in step 9. Someone
69
+ combines two actions in one step and does them in the wrong order. The ten
70
+ rules attack exactly these failure modes, and the linter makes them
71
+ mechanical: the rules that can be checked as structure *are* checked as
72
+ structure, so compliance isn't a matter of discipline — it's a matter of
73
+ passing the gate.
74
+
75
+ Two rules (1 and 8) are phrase-list heuristics — tripwires, not proof. Under
76
+ fail-closed they still block, so they are deliberately narrow: they fire only
77
+ on clear hits. A foolproof gate that misfires on good drafts isn't foolproof,
78
+ it's a tax. The narrowness is documented in the code and tested.
79
+
80
+ ## Quickstart
81
+
82
+ Zero dependencies beyond Python 3.10+.
83
+
84
+ ```bash
85
+ cd proofit
86
+ PYTHONPATH=src python3 -m unittest discover -s tests # 65 offline tests
87
+ ```
88
+
89
+ Lint a draft:
90
+
91
+ ```bash
92
+ PYTHONPATH=src python3 -m proofit lint my-runbook.md
93
+ # violations listed as RULE n [location] ERROR — message + fix
94
+ # exit 1: REJECTED — fix and re-run
95
+ # exit 0: PASS — the runbook is locked down
96
+ ```
97
+
98
+ Print the blank template:
99
+
100
+ ```bash
101
+ PYTHONPATH=src python3 -m proofit template > my-runbook.md
102
+ ```
103
+
104
+ Or use it as a library:
105
+
106
+ ```python
107
+ from proofit import lint_text
108
+
109
+ result = lint_text(open("my-runbook.md").read())
110
+ if not result.passed:
111
+ for v in result.violations:
112
+ print(v.render())
113
+ ```
114
+
115
+ See `examples/run_local.py` for the full cycle (broken draft rejected,
116
+ fixed draft passes).
117
+
118
+ ## Inputs, outputs
119
+
120
+ - **Input:** a runbook draft in Markdown following the template shape
121
+ (`templates/runbook-template.md`, or print it with `python -m proofit
122
+ template`). Freeform Markdown is out of scope **by design, not by
123
+ accident**: the linter parses the template's sections, so a document that
124
+ isn't in the template shape fails wholesale on missing sections rather
125
+ than producing meaningful per-rule violations. Write it in the template,
126
+ get it checked — anything else isn't a bad runbook to proofit, it's not
127
+ a runbook at all.
128
+ - **Output:** a list of violations (`RULE n [location] ERROR — message`
129
+ plus a `fix:` line), and an exit code: 1 if any violation exists, 0 if
130
+ clean. Fail-closed — there is no warning level.
131
+
132
+ ## Worked example
133
+
134
+ `examples/example-1-lint-cycle.md` — the same workflow as a broken draft
135
+ (18 violations, rejected) and a fixed draft (passes). The fixture files
136
+ `examples/broken-runbook.md` and `examples/fixed-runbook.md` are the
137
+ actual inputs; the test suite asserts the broken one yields exactly 18
138
+ violations across all ten rules and the fixed one yields zero.
139
+
140
+ ## FAQ
141
+
142
+ **Does it check whether the runbook is *correct*?** No. It checks the
143
+ runbook's shape, not its truth — it can't tell whether a stated rate limit
144
+ is right or a recovery path works. It guarantees the workflow is fully
145
+ specified, not that it is wise.
146
+
147
+ **What if a heuristic fires on a good draft?** Rules 1 and 8 are narrow by
148
+ design, but false positives are possible (documented in `checks.py`). If
149
+ one blocks a draft you believe is correct, the honest move is to reword past
150
+ the tripwire — the rewording is usually clearer anyway — not to fork the
151
+ linter.
152
+
153
+ **Why fail-closed instead of warnings?** Because the skill's promise is
154
+ "unbreakable, zero-assumption directive." A warning you can ignore is the
155
+ opposite of idiot-proof. The gate is the product.
156
+
157
+ **Single-service workflow — do I need the routing section?** No. Rule 9 is
158
+ vacuous when no services are named. Delete the Routing Architecture section
159
+ and the check passes silently.
160
+
161
+ ## License
162
+
163
+ MIT. See LICENSE.
@@ -0,0 +1,147 @@
1
+ # proofit — fail-closed linter for locked-down runbooks
2
+
3
+ A runbook is a step-by-step procedure written so tightly that two different
4
+ people following it do the same thing and get the same result. proofit checks
5
+ a runbook draft against ten rules of workflow discipline — and **rejects the
6
+ draft if any rule is violated**. No warnings, no advisories. Fail-closed:
7
+ exit 1 until it's fixed, exit 0 when it's locked down.
8
+
9
+ It checks the runbook's **shape, not its truth**: it can tell you a step is
10
+ missing its verification block, not whether the verification would actually
11
+ work. A fully-specified unwise workflow passes; a wise but sloppy one doesn't.
12
+ That distinction is the whole product — see the FAQ.
13
+
14
+ No prerequisites. You don't need to know anything about this project's
15
+ history or any framework. The mechanism is the whole product.
16
+
17
+ *(Lineage: this is the front-facing conversion of the `proofit` skill from
18
+ Ryan's skill-suite, MIT. What changed in the conversion is documented in
19
+ CHANGELOG.md.)*
20
+
21
+ ## What it does
22
+
23
+ You write the runbook as Markdown in the template shape
24
+ (`templates/runbook-template.md` — or print it with `python -m proofit
25
+ template`):
26
+
27
+ - **Ground Rules & Prerequisites** — baseline, routing specs per service,
28
+ tools/items, expected outcome
29
+ - **Step-by-Step Directives** — numbered steps, each with **Do:** /
30
+ **Look for:** / **Verify:** / **If wrong:** / **Fix:**
31
+ - **Validation & Closure** — success condition plus consistency checkpoints
32
+
33
+ The linter parses that shape and runs ten checks:
34
+
35
+ | # | Rule | How it's checked |
36
+ |---|------|------------------|
37
+ | 1 | Remove every assumption | Heuristic: flags bare unlabeled directives ("Press Continue") and claims of automatic behavior ("is done automatically"). Narrow by design — see below. |
38
+ | 2 | All prerequisites upfront | Structure: the section must exist before step 1 and cover all eight fields (hardware, software, accounts, permissions, files, internet access, free-tier limits, starting state). |
39
+ | 3 | One action per step | Structure: each `Do:` holds exactly one verb-led action; steps numbered 1..N. |
40
+ | 4 | Concrete references | Flags bare UI nouns ("the button") and vague references ("open the file") with no visible label. Qualified nouns ("a confirmation dialog") don't fire. |
41
+ | 5 | Explain technical terms | Convention: where a glossary exists, every entry must match `Term (definition)`. Detecting undefined jargon *without* a glossary is out of scope — stated, not pretended. |
42
+ | 6 | Verification after every milestone | Structure: every step ends with a `Verify:` block in observable language ("displays", "exists", "contains"). |
43
+ | 7 | Immediate recovery | Structure: every step carries `If wrong:` + `Fix:`. |
44
+ | 8 | Never skip state changes | Heuristic: a `Do:` starting with a state-changing verb (open, close, install, …) must describe the resulting state in transition language ("a dialog appears"). Narrow by design. |
45
+ | 9 | Routing decisions upfront | Schema: per named service — when to use, free-tier limits, verbatim prompt, expected output format — plus rate-limit handling and error paths. |
46
+ | 10 | Finish with full validation | Structure: the document ends with Validation & Closure (never a step), with a success condition and a checklist. |
47
+
48
+ ## Why it works
49
+
50
+ Most workflow failures are specification failures, not execution failures.
51
+ Someone improvises mid-stream because the routing decision was never written
52
+ down. Someone skips a prerequisite because it was revealed in step 9. Someone
53
+ combines two actions in one step and does them in the wrong order. The ten
54
+ rules attack exactly these failure modes, and the linter makes them
55
+ mechanical: the rules that can be checked as structure *are* checked as
56
+ structure, so compliance isn't a matter of discipline — it's a matter of
57
+ passing the gate.
58
+
59
+ Two rules (1 and 8) are phrase-list heuristics — tripwires, not proof. Under
60
+ fail-closed they still block, so they are deliberately narrow: they fire only
61
+ on clear hits. A foolproof gate that misfires on good drafts isn't foolproof,
62
+ it's a tax. The narrowness is documented in the code and tested.
63
+
64
+ ## Quickstart
65
+
66
+ Zero dependencies beyond Python 3.10+.
67
+
68
+ ```bash
69
+ cd proofit
70
+ PYTHONPATH=src python3 -m unittest discover -s tests # 65 offline tests
71
+ ```
72
+
73
+ Lint a draft:
74
+
75
+ ```bash
76
+ PYTHONPATH=src python3 -m proofit lint my-runbook.md
77
+ # violations listed as RULE n [location] ERROR — message + fix
78
+ # exit 1: REJECTED — fix and re-run
79
+ # exit 0: PASS — the runbook is locked down
80
+ ```
81
+
82
+ Print the blank template:
83
+
84
+ ```bash
85
+ PYTHONPATH=src python3 -m proofit template > my-runbook.md
86
+ ```
87
+
88
+ Or use it as a library:
89
+
90
+ ```python
91
+ from proofit import lint_text
92
+
93
+ result = lint_text(open("my-runbook.md").read())
94
+ if not result.passed:
95
+ for v in result.violations:
96
+ print(v.render())
97
+ ```
98
+
99
+ See `examples/run_local.py` for the full cycle (broken draft rejected,
100
+ fixed draft passes).
101
+
102
+ ## Inputs, outputs
103
+
104
+ - **Input:** a runbook draft in Markdown following the template shape
105
+ (`templates/runbook-template.md`, or print it with `python -m proofit
106
+ template`). Freeform Markdown is out of scope **by design, not by
107
+ accident**: the linter parses the template's sections, so a document that
108
+ isn't in the template shape fails wholesale on missing sections rather
109
+ than producing meaningful per-rule violations. Write it in the template,
110
+ get it checked — anything else isn't a bad runbook to proofit, it's not
111
+ a runbook at all.
112
+ - **Output:** a list of violations (`RULE n [location] ERROR — message`
113
+ plus a `fix:` line), and an exit code: 1 if any violation exists, 0 if
114
+ clean. Fail-closed — there is no warning level.
115
+
116
+ ## Worked example
117
+
118
+ `examples/example-1-lint-cycle.md` — the same workflow as a broken draft
119
+ (18 violations, rejected) and a fixed draft (passes). The fixture files
120
+ `examples/broken-runbook.md` and `examples/fixed-runbook.md` are the
121
+ actual inputs; the test suite asserts the broken one yields exactly 18
122
+ violations across all ten rules and the fixed one yields zero.
123
+
124
+ ## FAQ
125
+
126
+ **Does it check whether the runbook is *correct*?** No. It checks the
127
+ runbook's shape, not its truth — it can't tell whether a stated rate limit
128
+ is right or a recovery path works. It guarantees the workflow is fully
129
+ specified, not that it is wise.
130
+
131
+ **What if a heuristic fires on a good draft?** Rules 1 and 8 are narrow by
132
+ design, but false positives are possible (documented in `checks.py`). If
133
+ one blocks a draft you believe is correct, the honest move is to reword past
134
+ the tripwire — the rewording is usually clearer anyway — not to fork the
135
+ linter.
136
+
137
+ **Why fail-closed instead of warnings?** Because the skill's promise is
138
+ "unbreakable, zero-assumption directive." A warning you can ignore is the
139
+ opposite of idiot-proof. The gate is the product.
140
+
141
+ **Single-service workflow — do I need the routing section?** No. Rule 9 is
142
+ vacuous when no services are named. Delete the Routing Architecture section
143
+ and the check passes silently.
144
+
145
+ ## License
146
+
147
+ MIT. See LICENSE.
@@ -0,0 +1,30 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "frontface-proofit"
7
+ version = "1.0.0"
8
+ description = "Fail-closed linter for locked-down runbooks: ten rules of workflow discipline as code"
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ requires-python = ">=3.10"
12
+ authors = [{ name = "Ryan Wesley Hitchcock" }]
13
+ keywords = ["linter", "runbook", "workflow", "technical-writing", "validation"]
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ ]
19
+
20
+ [project.urls]
21
+ Homepage = "https://github.com/ohpersonperson/frontface"
22
+
23
+ [project.scripts]
24
+ proofit = "proofit.__main__:main"
25
+
26
+ [tool.setuptools.packages.find]
27
+ where = ["src"]
28
+
29
+ [tool.pytest.ini_options]
30
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,163 @@
1
+ Metadata-Version: 2.4
2
+ Name: frontface-proofit
3
+ Version: 1.0.0
4
+ Summary: Fail-closed linter for locked-down runbooks: ten rules of workflow discipline as code
5
+ Author: Ryan Wesley Hitchcock
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/ohpersonperson/frontface
8
+ Keywords: linter,runbook,workflow,technical-writing,validation
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.10
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Dynamic: license-file
16
+
17
+ # proofit — fail-closed linter for locked-down runbooks
18
+
19
+ A runbook is a step-by-step procedure written so tightly that two different
20
+ people following it do the same thing and get the same result. proofit checks
21
+ a runbook draft against ten rules of workflow discipline — and **rejects the
22
+ draft if any rule is violated**. No warnings, no advisories. Fail-closed:
23
+ exit 1 until it's fixed, exit 0 when it's locked down.
24
+
25
+ It checks the runbook's **shape, not its truth**: it can tell you a step is
26
+ missing its verification block, not whether the verification would actually
27
+ work. A fully-specified unwise workflow passes; a wise but sloppy one doesn't.
28
+ That distinction is the whole product — see the FAQ.
29
+
30
+ No prerequisites. You don't need to know anything about this project's
31
+ history or any framework. The mechanism is the whole product.
32
+
33
+ *(Lineage: this is the front-facing conversion of the `proofit` skill from
34
+ Ryan's skill-suite, MIT. What changed in the conversion is documented in
35
+ CHANGELOG.md.)*
36
+
37
+ ## What it does
38
+
39
+ You write the runbook as Markdown in the template shape
40
+ (`templates/runbook-template.md` — or print it with `python -m proofit
41
+ template`):
42
+
43
+ - **Ground Rules & Prerequisites** — baseline, routing specs per service,
44
+ tools/items, expected outcome
45
+ - **Step-by-Step Directives** — numbered steps, each with **Do:** /
46
+ **Look for:** / **Verify:** / **If wrong:** / **Fix:**
47
+ - **Validation & Closure** — success condition plus consistency checkpoints
48
+
49
+ The linter parses that shape and runs ten checks:
50
+
51
+ | # | Rule | How it's checked |
52
+ |---|------|------------------|
53
+ | 1 | Remove every assumption | Heuristic: flags bare unlabeled directives ("Press Continue") and claims of automatic behavior ("is done automatically"). Narrow by design — see below. |
54
+ | 2 | All prerequisites upfront | Structure: the section must exist before step 1 and cover all eight fields (hardware, software, accounts, permissions, files, internet access, free-tier limits, starting state). |
55
+ | 3 | One action per step | Structure: each `Do:` holds exactly one verb-led action; steps numbered 1..N. |
56
+ | 4 | Concrete references | Flags bare UI nouns ("the button") and vague references ("open the file") with no visible label. Qualified nouns ("a confirmation dialog") don't fire. |
57
+ | 5 | Explain technical terms | Convention: where a glossary exists, every entry must match `Term (definition)`. Detecting undefined jargon *without* a glossary is out of scope — stated, not pretended. |
58
+ | 6 | Verification after every milestone | Structure: every step ends with a `Verify:` block in observable language ("displays", "exists", "contains"). |
59
+ | 7 | Immediate recovery | Structure: every step carries `If wrong:` + `Fix:`. |
60
+ | 8 | Never skip state changes | Heuristic: a `Do:` starting with a state-changing verb (open, close, install, …) must describe the resulting state in transition language ("a dialog appears"). Narrow by design. |
61
+ | 9 | Routing decisions upfront | Schema: per named service — when to use, free-tier limits, verbatim prompt, expected output format — plus rate-limit handling and error paths. |
62
+ | 10 | Finish with full validation | Structure: the document ends with Validation & Closure (never a step), with a success condition and a checklist. |
63
+
64
+ ## Why it works
65
+
66
+ Most workflow failures are specification failures, not execution failures.
67
+ Someone improvises mid-stream because the routing decision was never written
68
+ down. Someone skips a prerequisite because it was revealed in step 9. Someone
69
+ combines two actions in one step and does them in the wrong order. The ten
70
+ rules attack exactly these failure modes, and the linter makes them
71
+ mechanical: the rules that can be checked as structure *are* checked as
72
+ structure, so compliance isn't a matter of discipline — it's a matter of
73
+ passing the gate.
74
+
75
+ Two rules (1 and 8) are phrase-list heuristics — tripwires, not proof. Under
76
+ fail-closed they still block, so they are deliberately narrow: they fire only
77
+ on clear hits. A foolproof gate that misfires on good drafts isn't foolproof,
78
+ it's a tax. The narrowness is documented in the code and tested.
79
+
80
+ ## Quickstart
81
+
82
+ Zero dependencies beyond Python 3.10+.
83
+
84
+ ```bash
85
+ cd proofit
86
+ PYTHONPATH=src python3 -m unittest discover -s tests # 65 offline tests
87
+ ```
88
+
89
+ Lint a draft:
90
+
91
+ ```bash
92
+ PYTHONPATH=src python3 -m proofit lint my-runbook.md
93
+ # violations listed as RULE n [location] ERROR — message + fix
94
+ # exit 1: REJECTED — fix and re-run
95
+ # exit 0: PASS — the runbook is locked down
96
+ ```
97
+
98
+ Print the blank template:
99
+
100
+ ```bash
101
+ PYTHONPATH=src python3 -m proofit template > my-runbook.md
102
+ ```
103
+
104
+ Or use it as a library:
105
+
106
+ ```python
107
+ from proofit import lint_text
108
+
109
+ result = lint_text(open("my-runbook.md").read())
110
+ if not result.passed:
111
+ for v in result.violations:
112
+ print(v.render())
113
+ ```
114
+
115
+ See `examples/run_local.py` for the full cycle (broken draft rejected,
116
+ fixed draft passes).
117
+
118
+ ## Inputs, outputs
119
+
120
+ - **Input:** a runbook draft in Markdown following the template shape
121
+ (`templates/runbook-template.md`, or print it with `python -m proofit
122
+ template`). Freeform Markdown is out of scope **by design, not by
123
+ accident**: the linter parses the template's sections, so a document that
124
+ isn't in the template shape fails wholesale on missing sections rather
125
+ than producing meaningful per-rule violations. Write it in the template,
126
+ get it checked — anything else isn't a bad runbook to proofit, it's not
127
+ a runbook at all.
128
+ - **Output:** a list of violations (`RULE n [location] ERROR — message`
129
+ plus a `fix:` line), and an exit code: 1 if any violation exists, 0 if
130
+ clean. Fail-closed — there is no warning level.
131
+
132
+ ## Worked example
133
+
134
+ `examples/example-1-lint-cycle.md` — the same workflow as a broken draft
135
+ (18 violations, rejected) and a fixed draft (passes). The fixture files
136
+ `examples/broken-runbook.md` and `examples/fixed-runbook.md` are the
137
+ actual inputs; the test suite asserts the broken one yields exactly 18
138
+ violations across all ten rules and the fixed one yields zero.
139
+
140
+ ## FAQ
141
+
142
+ **Does it check whether the runbook is *correct*?** No. It checks the
143
+ runbook's shape, not its truth — it can't tell whether a stated rate limit
144
+ is right or a recovery path works. It guarantees the workflow is fully
145
+ specified, not that it is wise.
146
+
147
+ **What if a heuristic fires on a good draft?** Rules 1 and 8 are narrow by
148
+ design, but false positives are possible (documented in `checks.py`). If
149
+ one blocks a draft you believe is correct, the honest move is to reword past
150
+ the tripwire — the rewording is usually clearer anyway — not to fork the
151
+ linter.
152
+
153
+ **Why fail-closed instead of warnings?** Because the skill's promise is
154
+ "unbreakable, zero-assumption directive." A warning you can ignore is the
155
+ opposite of idiot-proof. The gate is the product.
156
+
157
+ **Single-service workflow — do I need the routing section?** No. Rule 9 is
158
+ vacuous when no services are named. Delete the Routing Architecture section
159
+ and the check passes silently.
160
+
161
+ ## License
162
+
163
+ MIT. See LICENSE.
@@ -0,0 +1,20 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ src/frontface_proofit.egg-info/PKG-INFO
5
+ src/frontface_proofit.egg-info/SOURCES.txt
6
+ src/frontface_proofit.egg-info/dependency_links.txt
7
+ src/frontface_proofit.egg-info/entry_points.txt
8
+ src/frontface_proofit.egg-info/top_level.txt
9
+ src/proofit/__init__.py
10
+ src/proofit/__main__.py
11
+ src/proofit/checks.py
12
+ src/proofit/ledger.py
13
+ src/proofit/linter.py
14
+ src/proofit/model.py
15
+ src/proofit/parser.py
16
+ tests/test_cli.py
17
+ tests/test_ledger.py
18
+ tests/test_linter.py
19
+ tests/test_parser.py
20
+ tests/test_rules.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ proofit = proofit.__main__:main
@@ -0,0 +1,16 @@
1
+ """proofit — fail-closed linter for locked-down runbooks."""
2
+ from .linter import lint_file, lint_text
3
+ from .model import LintResult, Runbook, Step, Violation
4
+ from .parser import parse
5
+
6
+ __version__ = "1.0.0"
7
+ __all__ = [
8
+ "lint_file",
9
+ "lint_text",
10
+ "parse",
11
+ "LintResult",
12
+ "Runbook",
13
+ "Step",
14
+ "Violation",
15
+ "__version__",
16
+ ]