bad-decisions 1.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 (50) hide show
  1. bad_decisions-1.0.4/.gitignore +28 -0
  2. bad_decisions-1.0.4/AGENTS.md +73 -0
  3. bad_decisions-1.0.4/ATTRIBUTION.md +39 -0
  4. bad_decisions-1.0.4/CARDDECK.md +124 -0
  5. bad_decisions-1.0.4/DEPLOYMENT.md +53 -0
  6. bad_decisions-1.0.4/LICENSE +25 -0
  7. bad_decisions-1.0.4/LICENSES/CC-BY-NC-SA-2.0-legalcode.html +814 -0
  8. bad_decisions-1.0.4/LICENSES/CC-BY-NC-SA-2.0.txt +10 -0
  9. bad_decisions-1.0.4/LICENSES/CC-BY-SA-4.0-legalcode.html +1167 -0
  10. bad_decisions-1.0.4/LICENSES/CC-BY-SA-4.0.txt +8 -0
  11. bad_decisions-1.0.4/PKG-INFO +124 -0
  12. bad_decisions-1.0.4/README.md +84 -0
  13. bad_decisions-1.0.4/client/README.md +27 -0
  14. bad_decisions-1.0.4/client/pyproject.toml +27 -0
  15. bad_decisions-1.0.4/client/src/bad_decisions_client/__init__.py +3 -0
  16. bad_decisions-1.0.4/client/src/bad_decisions_client/cli.py +103 -0
  17. bad_decisions-1.0.4/client/tests/test_cli.py +41 -0
  18. bad_decisions-1.0.4/deploy/nginx.conf.example +20 -0
  19. bad_decisions-1.0.4/deploy/nginx.location.conf.example +12 -0
  20. bad_decisions-1.0.4/deploy/server.env.example +2 -0
  21. bad_decisions-1.0.4/deploy/server.service.template +22 -0
  22. bad_decisions-1.0.4/imports/base-validation.json +10 -0
  23. bad_decisions-1.0.4/imports/maha-migration.json +7 -0
  24. bad_decisions-1.0.4/imports/manifest.json +31 -0
  25. bad_decisions-1.0.4/pyproject.toml +37 -0
  26. bad_decisions-1.0.4/requirements-dev.lock +11 -0
  27. bad_decisions-1.0.4/requirements.lock +12 -0
  28. bad_decisions-1.0.4/scripts/import_coffee.py +123 -0
  29. bad_decisions-1.0.4/scripts/validate_packs.py +21 -0
  30. bad_decisions-1.0.4/src/bad_decisions/__init__.py +3 -0
  31. bad_decisions-1.0.4/src/bad_decisions/api.py +169 -0
  32. bad_decisions-1.0.4/src/bad_decisions/archive.py +199 -0
  33. bad_decisions-1.0.4/src/bad_decisions/cli.py +159 -0
  34. bad_decisions-1.0.4/src/bad_decisions/data/packs/base.json +3674 -0
  35. bad_decisions-1.0.4/src/bad_decisions/data/packs/maha.json +562 -0
  36. bad_decisions-1.0.4/src/bad_decisions/engine.py +56 -0
  37. bad_decisions-1.0.4/src/bad_decisions/errors.py +36 -0
  38. bad_decisions-1.0.4/src/bad_decisions/models.py +174 -0
  39. bad_decisions-1.0.4/src/bad_decisions/operations.py +93 -0
  40. bad_decisions-1.0.4/src/bad_decisions/packs.py +103 -0
  41. bad_decisions-1.0.4/src/bad_decisions/settings.py +22 -0
  42. bad_decisions-1.0.4/src/bad_decisions/web/app.js +90 -0
  43. bad_decisions-1.0.4/src/bad_decisions/web/index.html +81 -0
  44. bad_decisions-1.0.4/src/bad_decisions/web/style.css +46 -0
  45. bad_decisions-1.0.4/tests/conftest.py +49 -0
  46. bad_decisions-1.0.4/tests/test_archive.py +70 -0
  47. bad_decisions-1.0.4/tests/test_cli_api.py +78 -0
  48. bad_decisions-1.0.4/tests/test_models_engine.py +53 -0
  49. bad_decisions-1.0.4/tests/test_pack_ids.py +16 -0
  50. bad_decisions-1.0.4/tests/test_selectors.py +34 -0
@@ -0,0 +1,28 @@
1
+ # Python environments and caches
2
+ .venv/
3
+ .pypi-venv/
4
+ __pycache__/
5
+ *.py[cod]
6
+ .pytest_cache/
7
+
8
+ # Build and package artifacts
9
+ dist/
10
+ build/
11
+ *.egg-info/
12
+ client/dist/
13
+ client/build/
14
+ client/*.egg-info/
15
+ exports/
16
+
17
+ # Local configuration and secrets
18
+ .env
19
+ .env.*
20
+ *.env
21
+ !.env.example
22
+ *.pem
23
+ *.key
24
+
25
+ # Editor and operating-system metadata
26
+ .DS_Store
27
+ .vscode/
28
+ .idea/
@@ -0,0 +1,73 @@
1
+ # Bad Decisions contributor guide
2
+
3
+ > You are about to modify production infrastructure for a card game made from
4
+ > questionable decisions. Please make new questionable decisions deliberately.
5
+
6
+ This is an unofficial, unaffiliated fan project. It is absurd by design; its
7
+ validation, licenses, backups, and ZIP-bomb defenses are not.
8
+
9
+ ## Project map
10
+
11
+ - `src/bad_decisions/`: engine, pack models, CLI, API, and CardDeck support.
12
+ - `src/bad_decisions/data/packs/`: bundled, validated JSON packs.
13
+ - `client/`: separate dependency-free terminal-client distribution.
14
+ - `scripts/`: reproducible import/conversion utilities.
15
+ - `tests/`: pytest suite; keep behavioral and security coverage here.
16
+ - `deploy/` and `deploy.sh`: configurable systemd/nginx deployment tooling.
17
+
18
+ ## Working rules
19
+
20
+ - Preserve the API's immutable-runtime model. Packs are loaded at startup; do
21
+ not add API endpoints that import, upload, edit, or otherwise mutate packs.
22
+ - `BAD_DECISIONS_PACK_DIR` replaces the bundled registry. Use `bad-decisions pack init-registry`
23
+ before importing a portable pack when bundled packs should remain available.
24
+ - Keep CLI one-shot output clean: no banners, logs, or diagnostics on stdout.
25
+ - Maintain strict Pydantic validation and stable JSON error envelopes. Do not
26
+ silently coerce malformed pack data.
27
+ - Changes to archive parsing require hostile-input tests. Reject traversal,
28
+ symlinks, unexpected members, checksum failures, oversized content, and
29
+ dangerous compression ratios before writing to disk.
30
+ - Do not weaken the non-overwrite and atomic-write behavior of pack imports.
31
+
32
+ ## Content, attribution, and licensing
33
+
34
+ - Preserve card text, order, provenance, and licensing when migrating a source
35
+ pack unless the task explicitly authorizes a content transformation.
36
+ - Do not add third-party card data without recorded source, license evidence,
37
+ attribution, and redistribution compatibility.
38
+ - MAHA and owner-authorized custom material are CC BY-SA 4.0.
39
+ The bundled `base` pack remains CC BY-NC-SA 2.0; combined distributions must
40
+ honor its more restrictive terms.
41
+ - Do not publish raw source-message corpora or personal data. The Coffee pack
42
+ intentionally retains only compact source references.
43
+ - The project is an unofficial, unaffiliated fan project. Do not add Cards
44
+ Against Humanity logos, trade dress, or claims of endorsement.
45
+
46
+ ## Validation
47
+
48
+ Run before committing code changes:
49
+
50
+ ```bash
51
+ .venv/bin/python -m pytest
52
+ PYTHONPATH=client/src .venv/bin/python -m pytest client/tests
53
+ bash -n deploy.sh
54
+ ```
55
+
56
+ For a server release, build and validate the exact artifacts:
57
+
58
+ ```bash
59
+ .venv/bin/python -m build .
60
+ .venv/bin/python -m build client
61
+ .pypi-venv/bin/twine check dist/bad_decisions-* client/dist/bad_decisions_client-*
62
+ ```
63
+
64
+ ## Deployment and publishing
65
+
66
+ - `deploy.sh` must remain portable: do not hard-code a host name, domain, user
67
+ home, site file, or provider-specific network configuration.
68
+ - Require explicit configuration for an nginx site and public URL. Keep the
69
+ upstream loopback-only unless a deployment task explicitly says otherwise.
70
+ - PyPI versions are immutable. Check the current published version and bump it
71
+ before uploading; never rebuild different contents under an existing version.
72
+ - Never commit virtual environments, build artifacts, dotenv files, tokens, or
73
+ generated local exports.
@@ -0,0 +1,39 @@
1
+ # Attribution and content rights
2
+
3
+ ## Base pack
4
+
5
+ Cards Against Humanity by Cards Against Humanity LLC. The `base` pack is
6
+ extracted from the official 17-page downloadable main-game PDF created on
7
+ 2019-12-02 and retrieved on 2026-09-16:
8
+ <https://s3.amazonaws.com/cah/CAH_MainGame.pdf>. Its SHA-256 is
9
+ `92c8a719c6d7f28b89a87ecbfae780e7d4cd7472c97c7cf1ffe3037c2af89f9b`.
10
+
11
+ Page 17 states that the download is under Creative Commons BY-NC-SA 2.0.
12
+ Use is noncommercial, requires attribution, and adaptations are share-alike.
13
+ The authoritative legal code is preserved at
14
+ `LICENSES/CC-BY-NC-SA-2.0-legalcode.html`; the adjacent text file is a short
15
+ notice and link index, not a substitute for that legal code.
16
+ The importer collapses visual line wrapping, converts printed underscore runs
17
+ to anonymous template placeholders, and appends an answer on a new line to
18
+ question prompts without a printed blank. No endorsement is implied.
19
+
20
+ Imported coverage is exactly this edition: 80 black cards and 500 white cards.
21
+ Instructions, rules, and terms are excluded. Commercial expansions, future
22
+ releases, third-party decks, and the unverified “complete” online collections
23
+ are not included.
24
+
25
+ ## MAHA pack
26
+
27
+ The custom `maha` pack was migrated from the supplied `cah_maha.py`: 27 black
28
+ cards and 52 white cards. The project owner declared this content theirs and
29
+ created with ChatGPT assistance on 2026-09-16, authorizing this service
30
+ deployment. It is licensed as CC BY-SA 4.0; attribution and share-alike apply.
31
+ The authoritative legal code is preserved at
32
+ `LICENSES/CC-BY-SA-4.0-legalcode.html`. The migration adds metadata, IDs, pack
33
+ fields, and source references but preserves every original card field, order,
34
+ punctuation, and duplicate.
35
+
36
+ ## Software
37
+
38
+ New engine code is MIT-licensed. That license does not cover card data or
39
+ inherited code with unknown rights.
@@ -0,0 +1,124 @@
1
+ # CardDeck 1: portable card-pack format
2
+
3
+ CardDeck is a small, offline interchange format for card packs compatible with
4
+ fill-in-the-blank card-game engines. A CardDeck archive is a ZIP file named
5
+ with the `.carddeck` extension. This document defines version 1.
6
+
7
+ The key words **MUST**, **MUST NOT**, **REQUIRED**, **SHOULD**, **SHOULD NOT**,
8
+ and **MAY** are to be interpreted as described by RFC 2119.
9
+
10
+ ## Goals
11
+
12
+ - One file contains a validated card pack and its attribution/license text.
13
+ - An implementation can inspect or validate it without network access.
14
+ - The archive cannot silently change a running service; importing is an
15
+ explicit local administrator action.
16
+ - Stable card identities and provenance survive sharing between registries.
17
+
18
+ ## Archive layout
19
+
20
+ A conforming version-1 archive MUST contain exactly these four regular files at
21
+ its ZIP root. Directory entries and additional files are not allowed.
22
+
23
+ ```text
24
+ manifest.json
25
+ pack.json
26
+ LICENSE.txt
27
+ ATTRIBUTION.md
28
+ ```
29
+
30
+ Member names MUST be plain basenames. They MUST NOT contain path separators,
31
+ `.` or `..` path components, or symbolic links. `LICENSE.txt` and
32
+ `ATTRIBUTION.md` MUST be non-empty UTF-8 text.
33
+
34
+ ## Manifest
35
+
36
+ `manifest.json` MUST be UTF-8 JSON conforming to
37
+ [`schemas/carddeck-manifest-v1.schema.json`](schemas/carddeck-manifest-v1.schema.json).
38
+ It has no extension fields in version 1.
39
+
40
+ ```json
41
+ {
42
+ "format": "carddeck",
43
+ "format_version": 1,
44
+ "pack_id": "example-pack",
45
+ "pack_sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
46
+ }
47
+ ```
48
+
49
+ `pack_sha256` is the lowercase hexadecimal SHA-256 digest of the exact,
50
+ uncompressed bytes in `pack.json`; it is not a digest of re-serialized JSON.
51
+ `pack_id` MUST equal `pack.json`'s `metadata.id` and match
52
+ `^[a-z0-9][a-z0-9_-]*$`. The ID `all` is reserved.
53
+
54
+ ## Pack payload
55
+
56
+ `pack.json` is UTF-8 JSON with `schema_version: 1`. It contains:
57
+
58
+ ```text
59
+ schema_version
60
+ metadata
61
+ black
62
+ white
63
+ ```
64
+
65
+ `metadata` MUST include a stable ID, name, description, version, language,
66
+ custom flag, authors, attribution, license ID, license notice, sources, and
67
+ modifications. It MAY include `license_url`.
68
+
69
+ Each black card has a unique ID, `repr`, `template`, positive integer `slots`,
70
+ and its pack ID. Its template MAY use only anonymous `{}` fields and escaped
71
+ `{{`/`}}`; the number of anonymous fields MUST equal `slots`. Each white card
72
+ has a unique ID, non-empty `text`, and its pack ID. A pack MUST contain at least
73
+ one card. Card IDs are unique across both colors. Implementations SHOULD retain
74
+ optional `source_ref` values as provenance without treating them as executable
75
+ or network-resolvable references.
76
+
77
+ The pack metadata's attribution and license notice describe the cards, while
78
+ the adjacent files provide the human-readable material needed to redistribute
79
+ them. Pack authors are responsible for having the rights necessary to share
80
+ their card text and source references.
81
+
82
+ ## Validation and import
83
+
84
+ A conforming importer MUST, before writing anything:
85
+
86
+ 1. Reject a missing, malformed, unsupported, or checksum-mismatched manifest.
87
+ 2. Reject an archive whose member set differs from the required layout.
88
+ 3. Reject invalid pack data, mismatched pack IDs, empty license/attribution
89
+ files, unsafe paths, symlinks, or duplicate card IDs.
90
+ 4. Enforce documented size and decompression limits to mitigate ZIP bombs.
91
+
92
+ An importer MUST NOT overwrite an existing `<pack_id>.json` without an
93
+ explicit separate overwrite policy. It SHOULD write to a temporary file in the
94
+ target registry and atomically replace only that temporary file into place.
95
+
96
+ The reference implementation limits each member to 2 MiB, the archive payload
97
+ to 5 MiB, and a member's compression ratio to 100:1. Other implementations MAY
98
+ choose stricter limits but SHOULD document them.
99
+
100
+ Importing a CardDeck archive does not require, authorize, or imply a runtime API
101
+ upload. A server SHOULD load its registry only at startup and require an
102
+ operator-controlled restart after its registry changes.
103
+
104
+ ## Export
105
+
106
+ Exporters SHOULD emit only the four required files and SHOULD use a stable JSON
107
+ serialization for generated `pack.json`. They MUST calculate `pack_sha256`
108
+ from the actual bytes they place in the archive. Deterministic ZIP metadata is
109
+ recommended but is not required for conformance.
110
+
111
+ ## Compatibility
112
+
113
+ Consumers MUST reject `format_version` values they do not understand. A future
114
+ CardDeck versions may add capabilities only through a new version; version-1
115
+ readers MUST NOT silently accept unknown archive members or manifest fields.
116
+
117
+ ## Reference commands
118
+
119
+ ```bash
120
+ bad-decisions pack validate example.carddeck
121
+ bad-decisions pack export example ./example.carddeck
122
+ bad-decisions pack init-registry /absolute/pack/registry
123
+ bad-decisions pack import example.carddeck /absolute/pack/registry
124
+ ```
@@ -0,0 +1,53 @@
1
+ # Portable deployment
2
+
3
+ `deploy.sh` deploys this project to a Linux host using systemd and nginx. It is
4
+ deliberately parameterized: it does not name a provider, host, domain, user
5
+ home, or pre-existing nginx site.
6
+
7
+ Install Python 3.12 with venv support, nginx, and curl. Build and test the
8
+ project first. The script must run as root because it creates a service account,
9
+ release directory, systemd unit, environment file, and nginx configuration.
10
+
11
+ ## Configure the target server block
12
+
13
+ Select the existing nginx server configuration that should expose the API. Add
14
+ this exact marker inside the appropriate `server` block, then validate nginx:
15
+
16
+ ```nginx
17
+ # bad-decisions-location
18
+ ```
19
+
20
+ The marker lets the deployer insert one managed `include` without replacing or
21
+ guessing at the rest of your nginx configuration.
22
+
23
+ ## Deploy
24
+
25
+ ```bash
26
+ sudo NGINX_SITE_CONFIG=/etc/nginx/sites-available/example.com \
27
+ PUBLIC_BASE_URL=https://example.com/bad-decisions \
28
+ ./deploy.sh
29
+ ```
30
+
31
+ The supplied public URL is used only for the post-deployment HTTPS health
32
+ check. To deploy without nginx, use `CONFIGURE_NGINX=0`; no public check is
33
+ then performed.
34
+
35
+ ## Settings
36
+
37
+ | Setting | Default | Purpose |
38
+ | --- | --- | --- |
39
+ | `APP_NAME` | `bad-decisions` | Release directory and systemd service name. |
40
+ | `APP_ROOT` | `/opt/$APP_NAME` | Immutable release root. |
41
+ | `SERVICE_USER` | `$APP_NAME` | Locked system account that runs the API. |
42
+ | `ROOT_PATH` | `/bad-decisions` | Public nginx route and FastAPI root path. |
43
+ | `BIND_HOST` | `127.0.0.1` | Uvicorn bind address. Keep loopback-only behind nginx. |
44
+ | `PORT` | `8000` | Uvicorn port. |
45
+ | `WORKERS` | `2` | Uvicorn worker count. |
46
+ | `NGINX_SITE_CONFIG` | required when nginx is enabled | Existing server configuration containing the marker. |
47
+ | `PUBLIC_BASE_URL` | required when nginx is enabled | HTTPS URL corresponding to `ROOT_PATH`. |
48
+ | `CONFIGURE_NGINX` | `1` | Set to `0` to install only the systemd service. |
49
+
50
+ For an update, rerun the same command. The script builds a wheel, stages an
51
+ immutable release, atomically switches `current`, restarts the service, and
52
+ retains the prior healthy release for rollback. Inspect service logs with
53
+ `journalctl -u <APP_NAME> -n 100 --no-pager`.
@@ -0,0 +1,25 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MAHA card engine contributors
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.
22
+
23
+ This license applies only to newly written engine/import/deployment code. Card
24
+ data and inherited code are excluded and retain the rights stated in pack
25
+ metadata and ATTRIBUTION.md.