Metadata-Version: 2.5
Name: gcheck-core
Version: 0.4.1
Summary: Checklist engine of the Duniter/Ğ1 ecosystem, with the official gcheck checklists embedded
Project-URL: Homepage, https://gcheck-1be171.pages.duniter.org/
Project-URL: Repository, https://git.duniter.org/tools/gcheck
License-Expression: AGPL-3.0-or-later
License-File: LICENSE
Keywords: checklist,duniter,g1,gcheck,quiz
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Requires-Dist: pyyaml>=6
Description-Content-Type: text/markdown

# gcheck-core

Checklist engine of the [Duniter/Ğ1](https://duniter.org) ecosystem: it reads a
[gcheck](https://git.duniter.org/tools/gcheck) checklist (YAML or JSON), resolves its options,
selects the questions to ask and turns the answers into a verdict (pass, warning or fail).

The official checklists (member certification, smith commitments…) are embedded. They come from
the source of truth, [g1_monetary_license](https://git.duniter.org/documents/g1_monetary_license):
updating this dependency is enough to get their latest questions. An application can also provide
its own checklists, instead of or on top of the embedded ones.

The [Rust crate](https://crates.io/crates/gcheck-core) and the npm package of the same name offer
the same API and the same checklists; the three engines run shared test cases, so they cannot
drift apart.

## Usage

```python
from gcheck_core import Catalog, GcheckEngine, SMITH_ASPIRANT

catalog = Catalog.embedded()
# …optionally, the application's own checklists, which take precedence:
# catalog.add_content("my-checklist", my_yaml_or_json)

checklist = catalog.get(SMITH_ASPIRANT, "fr")
engine = GcheckEngine()
quiz = engine.prepare(checklist.content)

answers = {question.id: ask(question.text) for question in quiz.questions}  # your UI here

verdict = engine.evaluate(quiz, answers)  # "pass" | "warning" | "fail"
for issue in verdict.issues:
    print(issue.text, "expected:", issue.expected, issue.message)
```

- `quiz.checklist_hash` is the content hash of the checklist that was gone through: store it with
  the result, compare it later to know whether the checklist changed since. The Rust and
  TypeScript engines compute the same value.
- `all_checklists()` lists the embedded checklists, `get_checklist(id, lang)` picks one (falling
  back to English, then to any available language).
- `external_checklist(id, content)`, `checklist_from_file(path)` and `Catalog.add_dir(directory)`
  load checklists provided by the application.
- A `GcheckError` is raised when a checklist is invalid; it carries the same `code` as the other
  engines (`PARSE_ERROR`, `INVALID_SCHEMA`, `PICK_EXCEEDS_POOL`…).

## Checklist format

Checklists follow the
[checklist schema](https://git.duniter.org/tools/gcheck/-/blob/main/src/typescript/checklist.schema.json)
published by the source of truth.

## License

AGPL-3.0-or-later: GNU Affero General Public License, version 3 or (at your option) any later
version.
