docassert 0.5.0__tar.gz → 0.7.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.
- {docassert-0.5.0/docassert.egg-info → docassert-0.7.0}/PKG-INFO +9 -3
- {docassert-0.5.0 → docassert-0.7.0}/README.md +6 -2
- {docassert-0.5.0 → docassert-0.7.0}/docassert/__init__.py +1 -1
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/adr.criteria.yaml +6 -2
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/benefits-realization.criteria.yaml +6 -2
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/brd.criteria.yaml +5 -1
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/business-case.criteria.yaml +5 -1
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/charter.criteria.yaml +7 -3
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/data-migration-plan.criteria.yaml +6 -2
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/frnfr.criteria.yaml +5 -1
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/hypercare-plan.criteria.yaml +6 -2
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/post-implementation-review.criteria.yaml +5 -1
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/prd.criteria.yaml +5 -1
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/project.criteria.yaml +5 -1
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/qa-test-plan.criteria.yaml +6 -2
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/raci-stakeholder.criteria.yaml +6 -2
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/release-cutover-plan.criteria.yaml +6 -2
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/risk-register.criteria.yaml +6 -2
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/rollback-plan.criteria.yaml +6 -2
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/runbook.criteria.yaml +6 -2
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/status-report.criteria.yaml +6 -2
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/test-cases.criteria.yaml +5 -1
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/user-story.criteria.yaml +6 -2
- {docassert-0.5.0 → docassert-0.7.0}/docassert/cli.py +9 -1
- {docassert-0.5.0 → docassert-0.7.0}/docassert/consistency.py +4 -2
- {docassert-0.5.0 → docassert-0.7.0}/docassert/profiles.py +1 -1
- {docassert-0.5.0 → docassert-0.7.0}/docassert/semantic.py +1 -1
- {docassert-0.5.0 → docassert-0.7.0}/docassert/status.py +10 -2
- {docassert-0.5.0 → docassert-0.7.0}/docassert/structural.py +51 -9
- {docassert-0.5.0 → docassert-0.7.0/docassert.egg-info}/PKG-INFO +9 -3
- {docassert-0.5.0 → docassert-0.7.0}/docassert.egg-info/SOURCES.txt +2 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert.egg-info/requires.txt +2 -0
- {docassert-0.5.0 → docassert-0.7.0}/pyproject.toml +18 -1
- docassert-0.7.0/tests/test_badge.py +26 -0
- docassert-0.7.0/tests/test_draft_relaxation.py +138 -0
- {docassert-0.5.0 → docassert-0.7.0}/LICENSE +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/NOTICE +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/__main__.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/consistency.yaml +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/profiles/agile-delivery.yaml +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/profiles/lean-startup.yaml +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/profiles/regulated-industry.yaml +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/schema/adr.schema.json +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/schema/benefits-realization.schema.json +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/schema/brd.schema.json +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/schema/business-case.schema.json +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/schema/charter.schema.json +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/schema/data-migration-plan.schema.json +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/schema/frnfr.schema.json +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/schema/hypercare-plan.schema.json +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/schema/post-implementation-review.schema.json +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/schema/prd.schema.json +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/schema/project.schema.json +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/schema/qa-test-plan.schema.json +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/schema/raci-stakeholder.schema.json +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/schema/release-cutover-plan.schema.json +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/schema/risk-register.schema.json +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/schema/rollback-plan.schema.json +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/schema/runbook.schema.json +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/schema/status-report.schema.json +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/schema/test-cases.schema.json +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/schema/user-story.schema.json +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/skills/doc-to-pmo/SKILL.md +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/templates/adr.template.md +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/templates/benefits-realization.template.md +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/templates/brd.template.md +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/templates/business-case.template.md +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/templates/charter.template.md +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/templates/data-migration-plan.template.md +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/templates/frnfr.template.md +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/templates/hypercare-plan.template.md +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/templates/post-implementation-review.template.md +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/templates/prd.template.md +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/templates/project.template.md +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/templates/qa-test-plan.template.md +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/templates/raci-stakeholder.template.md +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/templates/release-cutover-plan.template.md +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/templates/risk-register.template.md +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/templates/rollback-plan.template.md +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/templates/runbook.template.md +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/templates/status-report.template.md +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/templates/test-cases.template.md +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/_data/templates/user-story.template.md +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/config.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/extract.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/graph.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/loader.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/models.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/projects.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/report.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/rtm.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert/scaffold.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert.egg-info/dependency_links.txt +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert.egg-info/entry_points.txt +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/docassert.egg-info/top_level.txt +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/setup.cfg +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/tests/test_config.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/tests/test_consistency.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/tests/test_defects.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/tests/test_extract.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/tests/test_graph.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/tests/test_json_report.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/tests/test_kinds_delivery.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/tests/test_kinds_governance.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/tests/test_kinds_operate.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/tests/test_kinds_reporting.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/tests/test_profiles.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/tests/test_projects.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/tests/test_scaffold.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/tests/test_status.py +0 -0
- {docassert-0.5.0 → docassert-0.7.0}/tests/test_structural.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: docassert
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Unit testing for business documents — validate structured Markdown docs against a configurable audit standard.
|
|
5
5
|
Author: C4G Enterprises Inc.
|
|
6
6
|
License: Apache-2.0
|
|
@@ -33,7 +33,9 @@ Requires-Dist: python-docx>=1.1; extra == "convert"
|
|
|
33
33
|
Requires-Dist: pypdf>=4.0; extra == "convert"
|
|
34
34
|
Provides-Extra: dev
|
|
35
35
|
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
36
|
+
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
36
37
|
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
38
|
+
Requires-Dist: mypy>=1.10; extra == "dev"
|
|
37
39
|
Dynamic: license-file
|
|
38
40
|
|
|
39
41
|
# docassert
|
|
@@ -49,7 +51,8 @@ semantic checks that advise. Requirements trace end to end, and project status i
|
|
|
49
51
|
derived from the documents rather than self-reported.
|
|
50
52
|
|
|
51
53
|
docassert is the reference implementation of **[PMO as Code](https://c4g-john.github.io/pmo-as-code/)** —
|
|
52
|
-
a vendor-neutral standard for running a PMO from version-controlled, declarative
|
|
54
|
+
a vendor-neutral standard for running a PMO from version-controlled, declarative
|
|
55
|
+
files. It implements the [PMO as Code specification](https://github.com/c4g-john/pmo-as-code-spec) **v0.1**.
|
|
53
56
|
|
|
54
57
|
## Install
|
|
55
58
|
|
|
@@ -89,7 +92,7 @@ flagged as TODOs, never invented). The skill's source is
|
|
|
89
92
|
| `docassert consistency` | Cross-document checks: referential integrity, coverage, required links, profile completeness. Reports: `--junit` / `--markdown` / `--json`. |
|
|
90
93
|
| `docassert rtm [--project ID]` | Requirements traceability matrix (Markdown or CSV). |
|
|
91
94
|
| `docassert status [--project ID] [--index]` | Derived project status (md / json / html). |
|
|
92
|
-
| `docassert pages --out DIR` | Build the portfolio site (index + a page per project). |
|
|
95
|
+
| `docassert pages --out DIR` | Build the portfolio site (index + a page per project + shields.io badge endpoints `badge.json` / `badges/<ID>.json`). |
|
|
93
96
|
| `docassert projects [--out] [--check]` | Generate / verify the project registry. |
|
|
94
97
|
| `docassert new <kind> --project ID` | Scaffold a document from its template with identity filled in (`new project --code XYZ` auto-numbers the id); suggests the next free item ids. |
|
|
95
98
|
| `docassert init [DIR]` | Scaffold the default config into a repo. |
|
|
@@ -114,6 +117,9 @@ kind is adding a trio — no code for the common cases.
|
|
|
114
117
|
- **Structural — deterministic, blocking.** Required fields and sections,
|
|
115
118
|
measurable success criteria, risks with owner + mitigation, resolving
|
|
116
119
|
references, unique ids. Plain Python, reliable enough to gate a merge.
|
|
120
|
+
Within this tier, *integrity* checks (malformed items, bad types, duplicate
|
|
121
|
+
ids) block at any status, while *completeness* checks relax to advisory on
|
|
122
|
+
`status: draft` and gate once a document is proposed — WIP is never punished.
|
|
117
123
|
- **Semantic — AI-graded, advisory.** Scored via the Anthropic API and posted to
|
|
118
124
|
the PR — never blocking. Set `ANTHROPIC_API_KEY` to enable; skipped otherwise.
|
|
119
125
|
|
|
@@ -11,7 +11,8 @@ semantic checks that advise. Requirements trace end to end, and project status i
|
|
|
11
11
|
derived from the documents rather than self-reported.
|
|
12
12
|
|
|
13
13
|
docassert is the reference implementation of **[PMO as Code](https://c4g-john.github.io/pmo-as-code/)** —
|
|
14
|
-
a vendor-neutral standard for running a PMO from version-controlled, declarative
|
|
14
|
+
a vendor-neutral standard for running a PMO from version-controlled, declarative
|
|
15
|
+
files. It implements the [PMO as Code specification](https://github.com/c4g-john/pmo-as-code-spec) **v0.1**.
|
|
15
16
|
|
|
16
17
|
## Install
|
|
17
18
|
|
|
@@ -51,7 +52,7 @@ flagged as TODOs, never invented). The skill's source is
|
|
|
51
52
|
| `docassert consistency` | Cross-document checks: referential integrity, coverage, required links, profile completeness. Reports: `--junit` / `--markdown` / `--json`. |
|
|
52
53
|
| `docassert rtm [--project ID]` | Requirements traceability matrix (Markdown or CSV). |
|
|
53
54
|
| `docassert status [--project ID] [--index]` | Derived project status (md / json / html). |
|
|
54
|
-
| `docassert pages --out DIR` | Build the portfolio site (index + a page per project). |
|
|
55
|
+
| `docassert pages --out DIR` | Build the portfolio site (index + a page per project + shields.io badge endpoints `badge.json` / `badges/<ID>.json`). |
|
|
55
56
|
| `docassert projects [--out] [--check]` | Generate / verify the project registry. |
|
|
56
57
|
| `docassert new <kind> --project ID` | Scaffold a document from its template with identity filled in (`new project --code XYZ` auto-numbers the id); suggests the next free item ids. |
|
|
57
58
|
| `docassert init [DIR]` | Scaffold the default config into a repo. |
|
|
@@ -76,6 +77,9 @@ kind is adding a trio — no code for the common cases.
|
|
|
76
77
|
- **Structural — deterministic, blocking.** Required fields and sections,
|
|
77
78
|
measurable success criteria, risks with owner + mitigation, resolving
|
|
78
79
|
references, unique ids. Plain Python, reliable enough to gate a merge.
|
|
80
|
+
Within this tier, *integrity* checks (malformed items, bad types, duplicate
|
|
81
|
+
ids) block at any status, while *completeness* checks relax to advisory on
|
|
82
|
+
`status: draft` and gate once a document is proposed — WIP is never punished.
|
|
79
83
|
- **Semantic — AI-graded, advisory.** Scored via the Anthropic API and posted to
|
|
80
84
|
the PR — never blocking. Set `ANTHROPIC_API_KEY` to enable; skipped otherwise.
|
|
81
85
|
|
|
@@ -18,9 +18,13 @@ checks:
|
|
|
18
18
|
type: structural
|
|
19
19
|
blocking: true
|
|
20
20
|
description: Frontmatter is valid against schema/adr.schema.json.
|
|
21
|
+
- id: frontmatter-complete
|
|
22
|
+
type: structural
|
|
23
|
+
blocking: once-proposed
|
|
24
|
+
description: Every schema-required frontmatter field is present (advisory while draft).
|
|
21
25
|
- id: required-sections
|
|
22
26
|
type: structural
|
|
23
|
-
blocking:
|
|
27
|
+
blocking: once-proposed
|
|
24
28
|
description: Every required section is present and non-empty.
|
|
25
29
|
- id: items-well-formed
|
|
26
30
|
type: structural
|
|
@@ -28,7 +32,7 @@ checks:
|
|
|
28
32
|
description: Every decision is a valid **ADR-###** item.
|
|
29
33
|
- id: adr-items-have-status
|
|
30
34
|
type: structural
|
|
31
|
-
blocking:
|
|
35
|
+
blocking: once-proposed
|
|
32
36
|
description: Every decision declares a valid Status (proposed | accepted | superseded | deprecated | rejected).
|
|
33
37
|
- id: unique-id
|
|
34
38
|
type: structural
|
{docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/benefits-realization.criteria.yaml
RENAMED
|
@@ -16,13 +16,17 @@ checks:
|
|
|
16
16
|
type: structural
|
|
17
17
|
blocking: true
|
|
18
18
|
description: Frontmatter is valid against schema/benefits-realization.schema.json.
|
|
19
|
+
- id: frontmatter-complete
|
|
20
|
+
type: structural
|
|
21
|
+
blocking: once-proposed
|
|
22
|
+
description: Every schema-required frontmatter field is present (advisory while draft).
|
|
19
23
|
- id: required-sections
|
|
20
24
|
type: structural
|
|
21
|
-
blocking:
|
|
25
|
+
blocking: once-proposed
|
|
22
26
|
description: Every required section is present and non-empty.
|
|
23
27
|
- id: measurable-items
|
|
24
28
|
type: structural
|
|
25
|
-
blocking:
|
|
29
|
+
blocking: once-proposed
|
|
26
30
|
description: Every benefit states a measurable target.
|
|
27
31
|
- id: unique-id
|
|
28
32
|
type: structural
|
|
@@ -16,9 +16,13 @@ checks:
|
|
|
16
16
|
type: structural
|
|
17
17
|
blocking: true
|
|
18
18
|
description: Frontmatter is valid against schema/brd.schema.json.
|
|
19
|
+
- id: frontmatter-complete
|
|
20
|
+
type: structural
|
|
21
|
+
blocking: once-proposed
|
|
22
|
+
description: Every schema-required frontmatter field is present (advisory while draft).
|
|
19
23
|
- id: required-sections
|
|
20
24
|
type: structural
|
|
21
|
-
blocking:
|
|
25
|
+
blocking: once-proposed
|
|
22
26
|
description: Every required section is present and non-empty.
|
|
23
27
|
- id: items-well-formed
|
|
24
28
|
type: structural
|
|
@@ -13,9 +13,13 @@ checks:
|
|
|
13
13
|
type: structural
|
|
14
14
|
blocking: true
|
|
15
15
|
description: Frontmatter is valid against schema/business-case.schema.json.
|
|
16
|
+
- id: frontmatter-complete
|
|
17
|
+
type: structural
|
|
18
|
+
blocking: once-proposed
|
|
19
|
+
description: Every schema-required frontmatter field is present (advisory while draft).
|
|
16
20
|
- id: required-sections
|
|
17
21
|
type: structural
|
|
18
|
-
blocking:
|
|
22
|
+
blocking: once-proposed
|
|
19
23
|
description: Every required section is present and non-empty.
|
|
20
24
|
- id: unique-id
|
|
21
25
|
type: structural
|
|
@@ -26,19 +26,23 @@ checks:
|
|
|
26
26
|
blocking: true
|
|
27
27
|
description: Frontmatter is present and valid against schema/charter.schema.json.
|
|
28
28
|
|
|
29
|
+
- id: frontmatter-complete
|
|
30
|
+
type: structural
|
|
31
|
+
blocking: once-proposed
|
|
32
|
+
description: Every schema-required frontmatter field is present (advisory while draft).
|
|
29
33
|
- id: required-sections
|
|
30
34
|
type: structural
|
|
31
|
-
blocking:
|
|
35
|
+
blocking: once-proposed
|
|
32
36
|
description: Every required section is present and non-empty.
|
|
33
37
|
|
|
34
38
|
- id: measurable-success-criteria
|
|
35
39
|
type: structural
|
|
36
|
-
blocking:
|
|
40
|
+
blocking: once-proposed
|
|
37
41
|
description: Every Success Criteria bullet states a measurable threshold (number, %, currency, or date).
|
|
38
42
|
|
|
39
43
|
- id: risks-have-owner-and-mitigation
|
|
40
44
|
type: structural
|
|
41
|
-
blocking:
|
|
45
|
+
blocking: once-proposed
|
|
42
46
|
description: Every Risks bullet names an Owner and a Mitigation.
|
|
43
47
|
|
|
44
48
|
- id: dates-consistent
|
{docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/data-migration-plan.criteria.yaml
RENAMED
|
@@ -14,13 +14,17 @@ checks:
|
|
|
14
14
|
type: structural
|
|
15
15
|
blocking: true
|
|
16
16
|
description: Frontmatter is valid against schema/data-migration-plan.schema.json.
|
|
17
|
+
- id: frontmatter-complete
|
|
18
|
+
type: structural
|
|
19
|
+
blocking: once-proposed
|
|
20
|
+
description: Every schema-required frontmatter field is present (advisory while draft).
|
|
17
21
|
- id: required-sections
|
|
18
22
|
type: structural
|
|
19
|
-
blocking:
|
|
23
|
+
blocking: once-proposed
|
|
20
24
|
description: Every required section is present and non-empty.
|
|
21
25
|
- id: mapping-table
|
|
22
26
|
type: structural
|
|
23
|
-
blocking:
|
|
27
|
+
blocking: once-proposed
|
|
24
28
|
description: The Field Mapping section contains a mapping table.
|
|
25
29
|
- id: unique-id
|
|
26
30
|
type: structural
|
|
@@ -17,9 +17,13 @@ checks:
|
|
|
17
17
|
type: structural
|
|
18
18
|
blocking: true
|
|
19
19
|
description: Frontmatter is valid against schema/frnfr.schema.json.
|
|
20
|
+
- id: frontmatter-complete
|
|
21
|
+
type: structural
|
|
22
|
+
blocking: once-proposed
|
|
23
|
+
description: Every schema-required frontmatter field is present (advisory while draft).
|
|
20
24
|
- id: required-sections
|
|
21
25
|
type: structural
|
|
22
|
-
blocking:
|
|
26
|
+
blocking: once-proposed
|
|
23
27
|
description: Every required section is present and non-empty.
|
|
24
28
|
- id: items-well-formed
|
|
25
29
|
type: structural
|
|
@@ -13,13 +13,17 @@ checks:
|
|
|
13
13
|
type: structural
|
|
14
14
|
blocking: true
|
|
15
15
|
description: Frontmatter is valid against schema/hypercare-plan.schema.json.
|
|
16
|
+
- id: frontmatter-complete
|
|
17
|
+
type: structural
|
|
18
|
+
blocking: once-proposed
|
|
19
|
+
description: Every schema-required frontmatter field is present (advisory while draft).
|
|
16
20
|
- id: required-sections
|
|
17
21
|
type: structural
|
|
18
|
-
blocking:
|
|
22
|
+
blocking: once-proposed
|
|
19
23
|
description: Every required section is present and non-empty.
|
|
20
24
|
- id: measurable-exit-criteria
|
|
21
25
|
type: structural
|
|
22
|
-
blocking:
|
|
26
|
+
blocking: once-proposed
|
|
23
27
|
description: Every hypercare exit criterion states a measurable threshold.
|
|
24
28
|
- id: unique-id
|
|
25
29
|
type: structural
|
|
@@ -14,9 +14,13 @@ checks:
|
|
|
14
14
|
type: structural
|
|
15
15
|
blocking: true
|
|
16
16
|
description: Frontmatter is valid against schema/post-implementation-review.schema.json.
|
|
17
|
+
- id: frontmatter-complete
|
|
18
|
+
type: structural
|
|
19
|
+
blocking: once-proposed
|
|
20
|
+
description: Every schema-required frontmatter field is present (advisory while draft).
|
|
17
21
|
- id: required-sections
|
|
18
22
|
type: structural
|
|
19
|
-
blocking:
|
|
23
|
+
blocking: once-proposed
|
|
20
24
|
description: Every required section is present and non-empty.
|
|
21
25
|
- id: unique-id
|
|
22
26
|
type: structural
|
|
@@ -17,9 +17,13 @@ checks:
|
|
|
17
17
|
type: structural
|
|
18
18
|
blocking: true
|
|
19
19
|
description: Frontmatter is valid against schema/prd.schema.json.
|
|
20
|
+
- id: frontmatter-complete
|
|
21
|
+
type: structural
|
|
22
|
+
blocking: once-proposed
|
|
23
|
+
description: Every schema-required frontmatter field is present (advisory while draft).
|
|
20
24
|
- id: required-sections
|
|
21
25
|
type: structural
|
|
22
|
-
blocking:
|
|
26
|
+
blocking: once-proposed
|
|
23
27
|
description: Every required section is present and non-empty.
|
|
24
28
|
- id: items-well-formed
|
|
25
29
|
type: structural
|
|
@@ -16,6 +16,10 @@ checks:
|
|
|
16
16
|
blocking: true
|
|
17
17
|
description: Frontmatter is present and valid against schema/project.schema.json.
|
|
18
18
|
|
|
19
|
+
- id: frontmatter-complete
|
|
20
|
+
type: structural
|
|
21
|
+
blocking: once-proposed
|
|
22
|
+
description: Every schema-required frontmatter field is present (advisory while draft).
|
|
19
23
|
- id: project-id-format
|
|
20
24
|
type: structural
|
|
21
25
|
blocking: true
|
|
@@ -23,7 +27,7 @@ checks:
|
|
|
23
27
|
|
|
24
28
|
- id: required-sections
|
|
25
29
|
type: structural
|
|
26
|
-
blocking:
|
|
30
|
+
blocking: once-proposed
|
|
27
31
|
description: Every required section is present and non-empty.
|
|
28
32
|
|
|
29
33
|
- id: unique-id
|
|
@@ -13,13 +13,17 @@ checks:
|
|
|
13
13
|
type: structural
|
|
14
14
|
blocking: true
|
|
15
15
|
description: Frontmatter is valid against schema/qa-test-plan.schema.json.
|
|
16
|
+
- id: frontmatter-complete
|
|
17
|
+
type: structural
|
|
18
|
+
blocking: once-proposed
|
|
19
|
+
description: Every schema-required frontmatter field is present (advisory while draft).
|
|
16
20
|
- id: required-sections
|
|
17
21
|
type: structural
|
|
18
|
-
blocking:
|
|
22
|
+
blocking: once-proposed
|
|
19
23
|
description: Every required section is present and non-empty.
|
|
20
24
|
- id: measurable-exit-criteria
|
|
21
25
|
type: structural
|
|
22
|
-
blocking:
|
|
26
|
+
blocking: once-proposed
|
|
23
27
|
description: Every exit criterion states a measurable threshold.
|
|
24
28
|
- id: unique-id
|
|
25
29
|
type: structural
|
|
@@ -10,13 +10,17 @@ checks:
|
|
|
10
10
|
type: structural
|
|
11
11
|
blocking: true
|
|
12
12
|
description: Frontmatter is valid against schema/raci-stakeholder.schema.json.
|
|
13
|
+
- id: frontmatter-complete
|
|
14
|
+
type: structural
|
|
15
|
+
blocking: once-proposed
|
|
16
|
+
description: Every schema-required frontmatter field is present (advisory while draft).
|
|
13
17
|
- id: required-sections
|
|
14
18
|
type: structural
|
|
15
|
-
blocking:
|
|
19
|
+
blocking: once-proposed
|
|
16
20
|
description: Every required section is present and non-empty.
|
|
17
21
|
- id: raci-one-accountable
|
|
18
22
|
type: structural
|
|
19
|
-
blocking:
|
|
23
|
+
blocking: once-proposed
|
|
20
24
|
description: Every activity in the RACI Matrix has exactly one Accountable (A) role.
|
|
21
25
|
- id: unique-id
|
|
22
26
|
type: structural
|
{docassert-0.5.0 → docassert-0.7.0}/docassert/_data/criteria/release-cutover-plan.criteria.yaml
RENAMED
|
@@ -16,13 +16,17 @@ checks:
|
|
|
16
16
|
type: structural
|
|
17
17
|
blocking: true
|
|
18
18
|
description: Frontmatter is valid against schema/release-cutover-plan.schema.json.
|
|
19
|
+
- id: frontmatter-complete
|
|
20
|
+
type: structural
|
|
21
|
+
blocking: once-proposed
|
|
22
|
+
description: Every schema-required frontmatter field is present (advisory while draft).
|
|
19
23
|
- id: required-sections
|
|
20
24
|
type: structural
|
|
21
|
-
blocking:
|
|
25
|
+
blocking: once-proposed
|
|
22
26
|
description: Every required section is present and non-empty.
|
|
23
27
|
- id: numbered-steps
|
|
24
28
|
type: structural
|
|
25
|
-
blocking:
|
|
29
|
+
blocking: once-proposed
|
|
26
30
|
description: Cutover Steps is an ordered list of at least two numbered steps.
|
|
27
31
|
- id: unique-id
|
|
28
32
|
type: structural
|
|
@@ -14,9 +14,13 @@ checks:
|
|
|
14
14
|
type: structural
|
|
15
15
|
blocking: true
|
|
16
16
|
description: Frontmatter is valid against schema/risk-register.schema.json.
|
|
17
|
+
- id: frontmatter-complete
|
|
18
|
+
type: structural
|
|
19
|
+
blocking: once-proposed
|
|
20
|
+
description: Every schema-required frontmatter field is present (advisory while draft).
|
|
17
21
|
- id: required-sections
|
|
18
22
|
type: structural
|
|
19
|
-
blocking:
|
|
23
|
+
blocking: once-proposed
|
|
20
24
|
description: Every required section is present and non-empty.
|
|
21
25
|
- id: items-well-formed
|
|
22
26
|
type: structural
|
|
@@ -24,7 +28,7 @@ checks:
|
|
|
24
28
|
description: Every risk is a valid **RISK-###** item.
|
|
25
29
|
- id: risk-items-complete
|
|
26
30
|
type: structural
|
|
27
|
-
blocking:
|
|
31
|
+
blocking: once-proposed
|
|
28
32
|
description: Every risk states a Probability, Impact, Owner, and Response.
|
|
29
33
|
- id: unique-id
|
|
30
34
|
type: structural
|
|
@@ -15,13 +15,17 @@ checks:
|
|
|
15
15
|
type: structural
|
|
16
16
|
blocking: true
|
|
17
17
|
description: Frontmatter is valid against schema/rollback-plan.schema.json.
|
|
18
|
+
- id: frontmatter-complete
|
|
19
|
+
type: structural
|
|
20
|
+
blocking: once-proposed
|
|
21
|
+
description: Every schema-required frontmatter field is present (advisory while draft).
|
|
18
22
|
- id: required-sections
|
|
19
23
|
type: structural
|
|
20
|
-
blocking:
|
|
24
|
+
blocking: once-proposed
|
|
21
25
|
description: Every required section is present and non-empty.
|
|
22
26
|
- id: numbered-steps
|
|
23
27
|
type: structural
|
|
24
|
-
blocking:
|
|
28
|
+
blocking: once-proposed
|
|
25
29
|
description: Rollback Steps is an ordered list of at least two numbered steps.
|
|
26
30
|
- id: unique-id
|
|
27
31
|
type: structural
|
|
@@ -16,13 +16,17 @@ checks:
|
|
|
16
16
|
type: structural
|
|
17
17
|
blocking: true
|
|
18
18
|
description: Frontmatter is valid against schema/runbook.schema.json.
|
|
19
|
+
- id: frontmatter-complete
|
|
20
|
+
type: structural
|
|
21
|
+
blocking: once-proposed
|
|
22
|
+
description: Every schema-required frontmatter field is present (advisory while draft).
|
|
19
23
|
- id: required-sections
|
|
20
24
|
type: structural
|
|
21
|
-
blocking:
|
|
25
|
+
blocking: once-proposed
|
|
22
26
|
description: Every required section is present and non-empty.
|
|
23
27
|
- id: numbered-steps
|
|
24
28
|
type: structural
|
|
25
|
-
blocking:
|
|
29
|
+
blocking: once-proposed
|
|
26
30
|
description: Procedures is an ordered list of at least two numbered steps.
|
|
27
31
|
- id: unique-id
|
|
28
32
|
type: structural
|
|
@@ -12,13 +12,17 @@ checks:
|
|
|
12
12
|
type: structural
|
|
13
13
|
blocking: true
|
|
14
14
|
description: Frontmatter is valid (includes a period date and a green/amber/red rag).
|
|
15
|
+
- id: frontmatter-complete
|
|
16
|
+
type: structural
|
|
17
|
+
blocking: once-proposed
|
|
18
|
+
description: Every schema-required frontmatter field is present (advisory while draft).
|
|
15
19
|
- id: required-sections
|
|
16
20
|
type: structural
|
|
17
|
-
blocking:
|
|
21
|
+
blocking: once-proposed
|
|
18
22
|
description: Every required section is present and non-empty.
|
|
19
23
|
- id: references-risk
|
|
20
24
|
type: structural
|
|
21
|
-
blocking:
|
|
25
|
+
blocking: once-proposed
|
|
22
26
|
description: The Risks & Issues section cites at least one RISK-### from the register.
|
|
23
27
|
- id: unique-id
|
|
24
28
|
type: structural
|
|
@@ -14,9 +14,13 @@ checks:
|
|
|
14
14
|
type: structural
|
|
15
15
|
blocking: true
|
|
16
16
|
description: Frontmatter is valid against schema/test-cases.schema.json.
|
|
17
|
+
- id: frontmatter-complete
|
|
18
|
+
type: structural
|
|
19
|
+
blocking: once-proposed
|
|
20
|
+
description: Every schema-required frontmatter field is present (advisory while draft).
|
|
17
21
|
- id: required-sections
|
|
18
22
|
type: structural
|
|
19
|
-
blocking:
|
|
23
|
+
blocking: once-proposed
|
|
20
24
|
description: Every required section is present and non-empty.
|
|
21
25
|
- id: items-well-formed
|
|
22
26
|
type: structural
|
|
@@ -14,9 +14,13 @@ checks:
|
|
|
14
14
|
type: structural
|
|
15
15
|
blocking: true
|
|
16
16
|
description: Frontmatter is valid against schema/user-story.schema.json.
|
|
17
|
+
- id: frontmatter-complete
|
|
18
|
+
type: structural
|
|
19
|
+
blocking: once-proposed
|
|
20
|
+
description: Every schema-required frontmatter field is present (advisory while draft).
|
|
17
21
|
- id: required-sections
|
|
18
22
|
type: structural
|
|
19
|
-
blocking:
|
|
23
|
+
blocking: once-proposed
|
|
20
24
|
description: Every required section is present and non-empty.
|
|
21
25
|
- id: items-well-formed
|
|
22
26
|
type: structural
|
|
@@ -24,7 +28,7 @@ checks:
|
|
|
24
28
|
description: Every story is a valid **US-###** item.
|
|
25
29
|
- id: story-format
|
|
26
30
|
type: structural
|
|
27
|
-
blocking:
|
|
31
|
+
blocking: once-proposed
|
|
28
32
|
description: Every story follows "As a … I want … so that …".
|
|
29
33
|
- id: unique-id
|
|
30
34
|
type: structural
|
|
@@ -226,13 +226,21 @@ def cmd_pages(args: argparse.Namespace) -> int:
|
|
|
226
226
|
index = status_mod.build_index(docs_dir)
|
|
227
227
|
(out / "index.html").write_text(status_mod.render_index_html(index))
|
|
228
228
|
|
|
229
|
+
# shields.io endpoint badges: one for the portfolio, one per project
|
|
230
|
+
# (https://img.shields.io/endpoint?url=<site>/badge.json)
|
|
231
|
+
(out / "badge.json").write_text(
|
|
232
|
+
status_mod.render_badge_json(index["overall"]["rag"]))
|
|
233
|
+
(out / "badges").mkdir(exist_ok=True)
|
|
234
|
+
|
|
229
235
|
plist = projects_mod.load_projects(docs_dir)
|
|
230
236
|
for p in plist:
|
|
231
237
|
model = status_mod.build_status(docs_dir, project=p["id"])
|
|
232
238
|
(out / f"{p['id']}.html").write_text(status_mod.render_html(model))
|
|
239
|
+
(out / "badges" / f"{p['id']}.json").write_text(
|
|
240
|
+
status_mod.render_badge_json(model["rag"], label=p["code"].lower()))
|
|
233
241
|
|
|
234
242
|
(out / "RTM.md").write_text(rtm.render_markdown(build_graph(docs_dir)))
|
|
235
|
-
print(f"docassert: wrote {out}/ — index + {len(plist)} project page(s) + RTM.md "
|
|
243
|
+
print(f"docassert: wrote {out}/ — index + {len(plist)} project page(s) + badges + RTM.md "
|
|
236
244
|
f"(portfolio: {index['overall']['rag']})")
|
|
237
245
|
return 0
|
|
238
246
|
|
|
@@ -63,7 +63,8 @@ def check_referential_integrity(graph) -> CheckResult:
|
|
|
63
63
|
|
|
64
64
|
def check_required_links(graph, config) -> CheckResult:
|
|
65
65
|
required = config.get("required_links", {})
|
|
66
|
-
approved_orphans
|
|
66
|
+
approved_orphans: list[str] = []
|
|
67
|
+
draft_orphans: list[str] = []
|
|
67
68
|
for item in graph.all_items():
|
|
68
69
|
relation = required.get(item.type)
|
|
69
70
|
if relation and not item.targets(relation):
|
|
@@ -79,7 +80,8 @@ def check_required_links(graph, config) -> CheckResult:
|
|
|
79
80
|
|
|
80
81
|
|
|
81
82
|
def check_coverage(graph, config) -> CheckResult:
|
|
82
|
-
approved_gaps
|
|
83
|
+
approved_gaps: list[str] = []
|
|
84
|
+
draft_gaps: list[str] = []
|
|
83
85
|
for rule in config.get("coverage", []):
|
|
84
86
|
parent_prefix, relation = rule["parent"], rule["relation"]
|
|
85
87
|
by_prefix = rule.get("by_prefix")
|
|
@@ -73,7 +73,7 @@ def completeness(profile: dict, documents: list[dict], project_status: str) -> d
|
|
|
73
73
|
"""
|
|
74
74
|
by_kind: dict[str, list[dict]] = {}
|
|
75
75
|
for d in documents:
|
|
76
|
-
by_kind.setdefault(d.get("kind"), []).append(d)
|
|
76
|
+
by_kind.setdefault(str(d.get("kind") or ""), []).append(d)
|
|
77
77
|
|
|
78
78
|
required = [{"kind": k, "state": _kind_state(k, by_kind)} for k in profile["required"]]
|
|
79
79
|
recommended = [{"kind": k, "state": _kind_state(k, by_kind)} for k in profile["recommended"]]
|
|
@@ -69,7 +69,7 @@ def _grade(prompt: str, content: str, model: str) -> dict:
|
|
|
69
69
|
"content": f"AUDIT CRITERION:\n{prompt}\n\nDOCUMENT:\n{content}",
|
|
70
70
|
}],
|
|
71
71
|
)
|
|
72
|
-
text = "".join(block
|
|
72
|
+
text = "".join(getattr(block, "text", "") for block in message.content
|
|
73
73
|
if getattr(block, "type", None) == "text").strip()
|
|
74
74
|
# tolerate models that wrap JSON in prose or fences
|
|
75
75
|
start, end = text.find("{"), text.rfind("}")
|
|
@@ -128,9 +128,9 @@ def build_status(documents_dir=DOCUMENTS_DIR, project: str | None = None) -> dic
|
|
|
128
128
|
else:
|
|
129
129
|
docs = all_docs
|
|
130
130
|
|
|
131
|
-
id_index = {}
|
|
131
|
+
id_index: dict[str, list[str]] = {}
|
|
132
132
|
for d in all_docs: # uniqueness is always global
|
|
133
|
-
id_index.setdefault(d.id, []).append(d.path)
|
|
133
|
+
id_index.setdefault(d.id or "", []).append(d.path)
|
|
134
134
|
|
|
135
135
|
documents = [{
|
|
136
136
|
"kind": d.kind,
|
|
@@ -460,6 +460,14 @@ def render_html(model) -> str:
|
|
|
460
460
|
|
|
461
461
|
|
|
462
462
|
_RAG_COLOR = {"green": "var(--ok)", "amber": "var(--amber)", "red": "var(--bad)"}
|
|
463
|
+
_BADGE_COLOR = {"green": "brightgreen", "amber": "orange", "red": "red"}
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
def render_badge_json(rag: str, label: str = "pmo docs") -> str:
|
|
467
|
+
"""A shields.io endpoint payload (https://shields.io/badges/endpoint-badge),
|
|
468
|
+
so a README can carry a live derived-status badge."""
|
|
469
|
+
return json.dumps({"schemaVersion": 1, "label": label,
|
|
470
|
+
"message": rag, "color": _BADGE_COLOR[rag]}) + "\n"
|
|
463
471
|
|
|
464
472
|
|
|
465
473
|
def _index_card(p, esc) -> str:
|