hoodscript 1.3.0__tar.gz → 1.4.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.
- hoodscript-1.4.0/.claude/skills/align-prompt/SKILL.md +32 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/CHANGELOG.md +125 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/CONTRIBUTING.md +7 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/PKG-INFO +6 -2
- {hoodscript-1.3.0 → hoodscript-1.4.0}/README.md +5 -1
- {hoodscript-1.3.0 → hoodscript-1.4.0}/SECURITY.md +3 -2
- {hoodscript-1.3.0 → hoodscript-1.4.0}/docs/adr/0002-keyword-reconciliation.md +11 -5
- hoodscript-1.4.0/docs/hoodlib.md +105 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/pyproject.toml +3 -0
- hoodscript-1.4.0/scripts/align_prompt.py +288 -0
- hoodscript-1.4.0/scripts/coraal_hits.py +123 -0
- hoodscript-1.4.0/scripts/hooks/pre-commit +13 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodarcade/cli.py +17 -4
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodfarm/cli.py +18 -5
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodlib/__init__.py +2 -2
- hoodscript-1.4.0/src/hoodlib/chart.py +167 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/_version.py +2 -2
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/cli.py +36 -14
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/kernel/kernel.py +4 -1
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/linter.py +96 -0
- hoodscript-1.4.0/src/hoodscript/migrate.py +146 -0
- hoodscript-1.4.0/src/hoodscript/replay.py +325 -0
- hoodscript-1.4.0/src/hoodscript/sourcing.py +410 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/security/test_exec_sites.py +1 -1
- hoodscript-1.4.0/tests/test_align_prompt.py +108 -0
- hoodscript-1.4.0/tests/test_chart.py +91 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_cli.py +14 -0
- hoodscript-1.4.0/tests/test_coraal_hits.py +74 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_docs.py +1 -1
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_fmt.py +1 -1
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_kernel.py +14 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_lint.py +54 -0
- hoodscript-1.4.0/tests/test_migrate_sourcing.py +235 -0
- hoodscript-1.4.0/tests/test_replay.py +125 -0
- hoodscript-1.4.0/tests/test_rule_zero.py +112 -0
- hoodscript-1.4.0/tests/test_wheel_contents.py +34 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/.gitignore +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/CODE_OF_CONDUCT.md +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/LICENSE +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/SPRINT_PLAN.md +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/docs/adr/0001-token-pipeline-over-parser.md +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/docs/adr/0003-inclusive-ranges.md +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/docs/adr/0004-no-regional-dialect-overlays.md +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/docs/adr/README.md +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/docs/archive/HOODSCRIPT_COMPLETE_MASTER_SYSTEM.md +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/docs/archive/HOODSCRIPT_FULL_ENGINEERING_SUITE.md +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/docs/archive/HOODSCRIPT_UNSPRED_FEATURES_ROADMAP.md +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/docs/curriculum.md +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/docs/grammar.ebnf +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/docs/keywords.md +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/docs/onboarding.md +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/quickstart.ipynb +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/beatlab/stage1.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/beatlab/stage2.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/beatlab/stage3.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/beatlab/stage4.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/beatlab/stage5.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/cookout/stage1.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/cookout/stage2.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/cookout/stage3.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/cookout/stage4.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/cookout/stage5.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/dropday/stage1.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/dropday/stage2.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/dropday/stage3.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/dropday/stage4.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/dropday/stage5.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/level1.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/level2.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/level3.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/level4.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/level5.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/level6.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/level7.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/examples/solutions/level8.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/out.txt +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/playground/app.js +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/playground/bundle.js +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/playground/examples.js +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/playground/hoodscript-latest-py3-none-any.whl +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/playground/index.html +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/playground/style.css +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/playground/worker.js +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/scripts/build_playground.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/scripts/gen_ebnf.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/scripts/gen_keywords.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/scripts/hooks/pre-push +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/scripts/install-hooks.sh +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodarcade/__init__.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodarcade/core/runtime.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodarcade/core/ui.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodarcade/games/beatlab.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodarcade/games/cookout.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodarcade/games/dropday.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodfarm/__init__.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodfarm/drone.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodfarm/grid.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodfarm/levels.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodfarm/renderer.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodfarm/runner.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodlib/disk.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/__init__.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/__main__.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/cache.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/constants.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/debugger.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/errors/__init__.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/errors/catalog.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/errors/renderer.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/errors/translator.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/formatter.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/importer.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/kernel/__init__.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/kernel/__main__.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/kernel/installer.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/kernel/magics.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/lsp.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/migrator.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/patterns.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/repl.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/sandbox.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/stubs.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/traceback_handler.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/transpiler.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/tutor.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/hoodscript/zen.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/src/vibe.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/security/conftest.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/security/corpus/deep_nesting.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/security/corpus/fork_bomb.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/security/corpus/huge_literal.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/security/corpus/import_escapes.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/security/corpus/infinite_recursion.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/security/corpus/open_file.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/security/corpus/pathological_indent.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/security/corpus/runaway_output.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/security/corpus/runaway_time.hs +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/security/test_corpus.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/security/test_fuzz.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/security/test_sandbox.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_arcade.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_arcade_gates.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_conformance.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_debugger.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_errors.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_fuzz_ebnf.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_game_engine.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_grammar_canonical.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_grammar_ebnf.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_hoodlib_disk.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_importer.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_kernel_zmq.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_keywords_doc.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_learn.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_lsp_features.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_patterns.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_playground.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_release.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_repl.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_transpiler.py +0 -0
- {hoodscript-1.3.0 → hoodscript-1.4.0}/tests/test_vscode_extension.py +0 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: align-prompt
|
|
3
|
+
description: Align a pasted generation prompt (from Gemini or anywhere) with the current HoodScript release before implementing it. Use whenever the user pastes a prompt that names files, keywords, or features to build.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# align-prompt
|
|
7
|
+
|
|
8
|
+
The user pastes a generation prompt. Do not execute it as written. Do this:
|
|
9
|
+
|
|
10
|
+
1. Save the pasted prompt verbatim to `$SCRATCHPAD/prompt-in.md`.
|
|
11
|
+
2. Run the mechanical half:
|
|
12
|
+
```
|
|
13
|
+
python scripts/align_prompt.py $SCRATCHPAD/prompt-in.md -o $SCRATCHPAD/prompt-aligned.md --report $SCRATCHPAD/prompt-report.md
|
|
14
|
+
```
|
|
15
|
+
It rewrites the v1.0.0 lexicon to v1.1, swaps stale phrasing/paths/commands,
|
|
16
|
+
prefixes lines that ask for declined/dropped work with `[DECLINED …]` /
|
|
17
|
+
`[DROPPED …]` / `[NEVER …]`, and prepends the PROMPTS.md §0 brief.
|
|
18
|
+
3. Do the judgment half — diff the aligned scope against the tree:
|
|
19
|
+
- `git ls-files src tests examples docs`, CHANGELOG `[Unreleased]` and the
|
|
20
|
+
latest release section, `CLAUDE.md` "Current status".
|
|
21
|
+
- For each item in the aligned prompt, classify: **shipped** (on `main`,
|
|
22
|
+
cite the path), **declined/dropped** (cite ADR or CHANGELOG), **gap**
|
|
23
|
+
(not on disk — the only thing to implement), or **conflict** (asks for
|
|
24
|
+
something the standing brief forbids — say so, don't build it).
|
|
25
|
+
4. Show the user a short table (item → status → evidence) and the report's
|
|
26
|
+
flagged lines. Then implement only the **gap** rows, one sprint, under the
|
|
27
|
+
gate (`ruff check && pytest`), on the current branch rules (agents.md).
|
|
28
|
+
5. If the aligned prompt is worth keeping, record the reconciliation as a
|
|
29
|
+
PROMPTS.md §3.x section like §3.5 — mapping table + the short correct prompt.
|
|
30
|
+
|
|
31
|
+
Never: reintroduce `cook`/`serve`/`Facts`/`holler`/`libcst`; add a keyword;
|
|
32
|
+
build a dialect overlay (ADR-0004); create a tag.
|
|
@@ -5,6 +5,131 @@ Versioning: the keyword set is the public API; changing it is at least a minor b
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [1.4.0] — 2026-09-12
|
|
9
|
+
|
|
10
|
+
New library module, new CLI command, three new lint rules, and the prompt
|
|
11
|
+
aligner. Keyword set unchanged (v1.1).
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **Sourcing audit sprint** (PROMPTS.md §2.9, worked record §3.7). Every
|
|
16
|
+
keyword, pattern form, and the `*Trip` suffix re-run through
|
|
17
|
+
`lexical-sourcing.md` §5 with the sources open rather than remembered:
|
|
18
|
+
the nine Yale GDP pages fetched and quoted; Green's Dictionary of Slang
|
|
19
|
+
read entry by entry (variety labels and first-quotation years now in the
|
|
20
|
+
table); CORAAL grepped for the first time — 231 interviews, 1.39 M tokens,
|
|
21
|
+
via a mirror because the Oregon host refused connections; the Urban
|
|
22
|
+
Dictionary liability screen run on all Tier B words. Results and
|
|
23
|
+
corrections: `hoodscript/docs/linguistics.md` "Sourcing audit —
|
|
24
|
+
2026-09-12". Decisions for the owner: GRAMMAR.md "Sourcing audit
|
|
25
|
+
2026-09-12 — DRAFT" (`cap`/`no cap` liability + 2018 dating; `trip` now
|
|
26
|
+
two-source; `dip` meets the corpus clause; `tryna` re-ranked; Rickford →
|
|
27
|
+
Labov on the `ain't` row). No keyword changed.
|
|
28
|
+
- **`hoodscript migrate <file.hs>`** — rewrites v1.0.0 code to the v1.1
|
|
29
|
+
lexicon from the CHANGELOG migration table: two line-preserving token
|
|
30
|
+
passes (v1.0.0 map → Python → `py2hood`), so `cook`→`bet`, `serve`→`dip`,
|
|
31
|
+
`holler(x)`→`holla x`, `Facts`→`no cap`, `GhostFileTrip`→`MissingFileTrip`,
|
|
32
|
+
the 21 builtin aliases → their Python names. Auto-detects v1.0.0 by its
|
|
33
|
+
exclusive tokens (`dip` meant `break` there — a v1.1 file is left alone
|
|
34
|
+
with a note; `--from 1.0` forces). `-w` writes with a `.bak`; `--diff`.
|
|
35
|
+
Refuses to write if the line count changed. `align_prompt.py` fixed
|
|
36
|
+
prompts; this fixes code.
|
|
37
|
+
- **`hoodscript sourcing <word>`** — Rule Zero as one command
|
|
38
|
+
(`src/hoodscript/sourcing.py`): standing (keyword / cut / candidate, with
|
|
39
|
+
the `linguistics.md` rows when run from a checkout), Green's Dictionary of
|
|
40
|
+
Slang senses with variety labels and first-quotation years, the Urban
|
|
41
|
+
Dictionary liability screen by rank, CORAAL hits + KWIC with `--coraal`,
|
|
42
|
+
and the checklist of steps no script can do. `--offline`, `--json`. The
|
|
43
|
+
cut list now lives in `sourcing.CUT` (one source for the command and
|
|
44
|
+
`tests/test_rule_zero.py`); `scripts/coraal_hits.py` imports the corpus
|
|
45
|
+
code from here.
|
|
46
|
+
- `scripts/coraal_hits.py` — step 3 of the sourcing procedure as a tool:
|
|
47
|
+
counts every keyword in official CORAAL text files or a JSONL mirror,
|
|
48
|
+
`--kwic` prints the lines so senses can be read, not guessed.
|
|
49
|
+
- `tests/test_rule_zero.py` — the release package's constitutional test
|
|
50
|
+
(the prototype's `test_one_to_one_law.py` read the prototype's table and
|
|
51
|
+
never guarded `constants.py`): cut words stay cut (the full v1.0 + v1.1 +
|
|
52
|
+
alias cut list), tiers are disjoint, Tier B ≤ 9, every Tier A/B keyword
|
|
53
|
+
has a row in `linguistics.md`, Urban Dictionary never appears in a
|
|
54
|
+
citation row, the docs mention every keyword, and the screen matches red
|
|
55
|
+
flags on word boundaries.
|
|
56
|
+
|
|
57
|
+
### Fixed
|
|
58
|
+
|
|
59
|
+
- `hoodscript/scripts/screen_keyword.py` flagged `something` for `meth` and
|
|
60
|
+
`essex` for `sex` (substring matching); now word-boundary regexes. The UD
|
|
61
|
+
API has returned no vote counts since 2024, so the script reports UD's
|
|
62
|
+
own rank instead of a meaningless `score +0`.
|
|
63
|
+
- `hoodscript/docs/lexical-sourcing.md` §5 step 7 sent contributors to the
|
|
64
|
+
frozen prototype's `KEYWORD_TO_AST`; now `src/hoodscript/constants.py` +
|
|
65
|
+
`tests/test_conformance.py` + `docs/keywords.md`. Green's Dictionary of
|
|
66
|
+
Slang added to the Tier 3 table as the first dictionary to check.
|
|
67
|
+
- `docs/adr/0002` listed `tryna` and `chill` as Tier C (they are A and B);
|
|
68
|
+
CLAUDE.md/agents.md said 16 exception names (17); GRAMMAR.md's `*Trip`
|
|
69
|
+
list lacked `BadImportTrip`.
|
|
70
|
+
|
|
71
|
+
- **Creative-DX sprint** (from a pasted "Horizon & Creative DX" prompt, aligned
|
|
72
|
+
via `scripts/align_prompt.py`; reconciliation in PROMPTS.md §3.6). Built:
|
|
73
|
+
- **`hoodlib.chart`** — Braille/block sparklines, bar charts, histograms,
|
|
74
|
+
`show_bag()` for game inventories. Standard library only; every function
|
|
75
|
+
returns a string; empty/non-numeric input is a plain `BadValueTrip` /
|
|
76
|
+
`WrongKindTrip`. Documented with runnable examples in `docs/hoodlib.md`
|
|
77
|
+
(now part of the docs-are-tests set, together with `hoodlib.disk`).
|
|
78
|
+
- **`hoodscript replay <file.hs>`** — run a program under `sys.settrace`,
|
|
79
|
+
then step through it backwards: `f`/`b`, `j N`, `l N` (first step at a
|
|
80
|
+
line), `v` (locals), `w` (caller chain). Snapshots are deep copies;
|
|
81
|
+
uncopyable values are stored as `repr`; `--max-steps` caps memory;
|
|
82
|
+
`--dump` prints the trace for pipes. A crash is reported by the JPE
|
|
83
|
+
engine and the prompt opens *at* the crash so `b` steps back from it.
|
|
84
|
+
The 1:1 line law is what makes this cheap: trace lines are `.hs` lines.
|
|
85
|
+
- **Lint HL004–HL006** — exact `ast` rules, no tool needed: a secret-looking
|
|
86
|
+
name assigned a real-looking string literal (placeholders and
|
|
87
|
+
`os.environ` reads are ignored); nesting deeper than four blocks inside
|
|
88
|
+
a function (one finding per chain); a function that is one big `if`
|
|
89
|
+
(guard-clause opportunity). Plain-English what/why/fix like HL001–HL003.
|
|
90
|
+
Declined from the same prompt, with reasons: a `pass_to` pipe operator
|
|
91
|
+
(a new keyword without a citation, and `g(f(x))` rewriting is not one
|
|
92
|
+
construct per construct — Rule Zero and the 1:1 law), voice-to-code
|
|
93
|
+
(`hoodscript mic`: a speech stack the zero-dep core forbids, and a spoken
|
|
94
|
+
dialect map — ADR-0004 in audio). Dropped: BeatMode audio cues (not a
|
|
95
|
+
language feature, untestable in CI), a `hoodlib.tui` DSL over Rich (Rich is
|
|
96
|
+
the DSL), `hoodlib.collections` query wrappers (comprehensions, `sorted`,
|
|
97
|
+
`itertools.groupby`, `Counter`), and a 0–10 "Vibe Score" (not actionable;
|
|
98
|
+
its real rules became HL004–HL006).
|
|
99
|
+
|
|
100
|
+
- `scripts/align_prompt.py` + `/align-prompt` skill: rewrites a stale
|
|
101
|
+
generation prompt to the current release (v1.1 lexicon, line law wording,
|
|
102
|
+
current paths/commands), marks lines that ask for declined or dropped work
|
|
103
|
+
(`[DECLINED — ADR-0004]`, `[DROPPED …]`, `[NEVER — libcst]`), prepends the
|
|
104
|
+
PROMPTS.md §0 brief, and prints a change report. Prose is left alone —
|
|
105
|
+
English words that are also v1.0.0 tokens (`say`, `cut`, `word`, `mine`…)
|
|
106
|
+
are rewritten only in code context. Idempotent. PROMPTS.md §3.5.
|
|
107
|
+
|
|
108
|
+
## [1.3.1] — 2026-09-12
|
|
109
|
+
|
|
110
|
+
Patch release: what the fresh-machine check of 1.3.0 found, plus two audit
|
|
111
|
+
leftovers. No keyword or API changes.
|
|
112
|
+
|
|
113
|
+
### Fixed
|
|
114
|
+
|
|
115
|
+
- Fresh-machine check of v1.3.0 (`pip install "hoodscript[all]"` in a clean
|
|
116
|
+
venv, `docs/onboarding.md` §2–§11 verbatim): everything passed except
|
|
117
|
+
`hoodfarm test` and `hoodarcade test`, which reported "No Sol" for every
|
|
118
|
+
level and **exited 0** — the reference solutions were not in the wheel and a
|
|
119
|
+
missing solution counted as a pass. The solutions now ship
|
|
120
|
+
(`hoodscript/data/solutions`, found by both CLIs after the repo checkout), a
|
|
121
|
+
missing one is a red `MISSING` row and a non-zero exit, and
|
|
122
|
+
`tests/test_wheel_contents.py` builds the wheel and asserts the runtime
|
|
123
|
+
data (curriculum, `vibe.py`, solutions) is inside it.
|
|
124
|
+
|
|
125
|
+
- `hoodscript --sandbox run f.hs` now works (the flags may come before or after
|
|
126
|
+
`run`; `run` is recognised as the first positional, not only as `argv[0]`).
|
|
127
|
+
- Jupyter: `%hood_tb` is honoured by the error card — the Python traceback
|
|
128
|
+
section opens by default and the plain-text fallback carries it too.
|
|
129
|
+
- MANUAL §16 documents that `hoodscript fmt` writes `ain't nobody x` back as
|
|
130
|
+
`ain't x` (same Python, one canonical spelling).
|
|
131
|
+
- `cli.py` had the `arcade` dispatch block twice; the copy is gone.
|
|
132
|
+
|
|
8
133
|
## [1.3.0] — 2026-09-12
|
|
9
134
|
|
|
10
135
|
Three features that were on `main` but not on PyPI: the two games and the
|
|
@@ -126,6 +126,13 @@ and the end-to-end audit in [`PROMPTS.md`](PROMPTS.md) §2.8, and only then
|
|
|
126
126
|
merges. Two batches arrived on 2026-09-11 claiming completion with defects
|
|
127
127
|
their own tests could not see; that is why.
|
|
128
128
|
|
|
129
|
+
Concretely, for an agent (decided 2026-09-12): it works on a `gemini/<topic>`
|
|
130
|
+
branch — never on `main`, never in a checkout another agent is using — pushes
|
|
131
|
+
it, opens a PR with `.github/PULL_REQUEST_TEMPLATE.md` filled in, and stops.
|
|
132
|
+
The `scripts/hooks/pre-commit` hook refuses commits on `main` unless
|
|
133
|
+
`git config hoodscript.owner` matches `user.email` (the owner sets it once;
|
|
134
|
+
`scripts/install-hooks.sh` installs the hooks).
|
|
135
|
+
|
|
129
136
|
## Working with an AI agent
|
|
130
137
|
|
|
131
138
|
Paste the standing brief from [`PROMPTS.md`](PROMPTS.md) §0 at the top of
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: hoodscript
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: A production-grade Python 3 conlang based on AAVE with 1:1 AST parity.
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -110,7 +110,10 @@ hoodscript -c hello.hs # print the Python it becomes
|
|
|
110
110
|
hoodscript repl --mirror # interactive REPL (hood> prompt; chill to exit; --mirror shows the Python)
|
|
111
111
|
hoodscript playground # launch in-browser Pyodide WebAssembly playground
|
|
112
112
|
hoodscript kernel install # Jupyter kernel (pip install "hoodscript[jupyter]"); or %load_ext hoodscript
|
|
113
|
-
hoodscript fmt|lint <file.hs> # formatter / linter (pip install "hoodscript[tools]")
|
|
113
|
+
hoodscript fmt|lint <file.hs> # formatter / linter (pip install "hoodscript[tools]"); lint has HL001–HL006
|
|
114
|
+
hoodscript replay <file.hs> # run it, then step through it backwards (b/f/j/l/v/w); --dump prints all
|
|
115
|
+
hoodscript migrate <file.hs> # rewrite v1.0.0 code (cook/serve/holler/Facts…) to the v1.1 lexicon; -w writes, --diff shows
|
|
116
|
+
hoodscript sourcing <word> # Rule Zero check: standing, Green's Dictionary of Slang, UD liability screen, --coraal PATH
|
|
114
117
|
hoodscript learn [topic] # interactive tutor driving docs/curriculum.md
|
|
115
118
|
hoodscript # a short tour of all commands
|
|
116
119
|
hoodscript zen # the Zen of HoodScript (HPEP 20); or `import vibe`
|
|
@@ -196,6 +199,7 @@ hoodarcade play cookout 1 # edit the solution file; the stage re-runs on s
|
|
|
196
199
|
- [`docs/onboarding.md`](docs/onboarding.md) — from zero to a running program in ten minutes
|
|
197
200
|
- [`docs/curriculum.md`](docs/curriculum.md) — ten lessons, each with a runnable file
|
|
198
201
|
- [`MANUAL.md`](MANUAL.md) — the full manual
|
|
202
|
+
- [`docs/hoodlib.md`](docs/hoodlib.md) — the small standard library: `chart` (sparklines, bars, histograms), `disk` (atomic files)
|
|
199
203
|
- [`agents.md`](agents.md) — architecture and subsystem walkthrough
|
|
200
204
|
- [`CLAUDE.md`](CLAUDE.md) — the standing brief for anyone (human or agent) changing the code
|
|
201
205
|
- [`SPRINT_PLAN.md`](SPRINT_PLAN.md) — what's next · [`CHANGELOG.md`](CHANGELOG.md) · [`CONTRIBUTING.md`](CONTRIBUTING.md)
|
|
@@ -60,7 +60,10 @@ hoodscript -c hello.hs # print the Python it becomes
|
|
|
60
60
|
hoodscript repl --mirror # interactive REPL (hood> prompt; chill to exit; --mirror shows the Python)
|
|
61
61
|
hoodscript playground # launch in-browser Pyodide WebAssembly playground
|
|
62
62
|
hoodscript kernel install # Jupyter kernel (pip install "hoodscript[jupyter]"); or %load_ext hoodscript
|
|
63
|
-
hoodscript fmt|lint <file.hs> # formatter / linter (pip install "hoodscript[tools]")
|
|
63
|
+
hoodscript fmt|lint <file.hs> # formatter / linter (pip install "hoodscript[tools]"); lint has HL001–HL006
|
|
64
|
+
hoodscript replay <file.hs> # run it, then step through it backwards (b/f/j/l/v/w); --dump prints all
|
|
65
|
+
hoodscript migrate <file.hs> # rewrite v1.0.0 code (cook/serve/holler/Facts…) to the v1.1 lexicon; -w writes, --diff shows
|
|
66
|
+
hoodscript sourcing <word> # Rule Zero check: standing, Green's Dictionary of Slang, UD liability screen, --coraal PATH
|
|
64
67
|
hoodscript learn [topic] # interactive tutor driving docs/curriculum.md
|
|
65
68
|
hoodscript # a short tour of all commands
|
|
66
69
|
hoodscript zen # the Zen of HoodScript (HPEP 20); or `import vibe`
|
|
@@ -146,6 +149,7 @@ hoodarcade play cookout 1 # edit the solution file; the stage re-runs on s
|
|
|
146
149
|
- [`docs/onboarding.md`](docs/onboarding.md) — from zero to a running program in ten minutes
|
|
147
150
|
- [`docs/curriculum.md`](docs/curriculum.md) — ten lessons, each with a runnable file
|
|
148
151
|
- [`MANUAL.md`](MANUAL.md) — the full manual
|
|
152
|
+
- [`docs/hoodlib.md`](docs/hoodlib.md) — the small standard library: `chart` (sparklines, bars, histograms), `disk` (atomic files)
|
|
149
153
|
- [`agents.md`](agents.md) — architecture and subsystem walkthrough
|
|
150
154
|
- [`CLAUDE.md`](CLAUDE.md) — the standing brief for anyone (human or agent) changing the code
|
|
151
155
|
- [`SPRINT_PLAN.md`](SPRINT_PLAN.md) — what's next · [`CHANGELOG.md`](CHANGELOG.md) · [`CONTRIBUTING.md`](CONTRIBUTING.md)
|
|
@@ -50,7 +50,7 @@ To protect host environments against runaway workloads, the sandbox enforces thr
|
|
|
50
50
|
|
|
51
51
|
## 4. Code Execution Audit
|
|
52
52
|
|
|
53
|
-
`exec`/`eval` appear in exactly
|
|
53
|
+
`exec`/`eval` appear in exactly seven places, all on code objects produced by
|
|
54
54
|
`compile()` from the transpiler's output of the user's own source — never on
|
|
55
55
|
text from anywhere else:
|
|
56
56
|
1. `src/hoodscript/cli.py` — running a file
|
|
@@ -59,7 +59,8 @@ text from anywhere else:
|
|
|
59
59
|
4. `src/hoodscript/tutor.py` — running a curriculum lesson
|
|
60
60
|
5. `src/hoodscript/kernel/kernel.py` — executing notebook cells in the HoodScript kernel
|
|
61
61
|
6. `src/hoodscript/kernel/magics.py` — executing `%%hood` cells in IPython / Google Colab
|
|
62
|
-
`
|
|
62
|
+
7. `src/hoodscript/replay.py` — running a file under the `sys.settrace` recorder (`hoodscript replay`)
|
|
63
|
+
`tests/security/test_exec_sites.py` fails if an eighth appears.
|
|
63
64
|
|
|
64
65
|
### Why this is safe and equivalent to `compile()`:
|
|
65
66
|
- `transpile()` performs strictly lexical substitution over Python's `tokenize.tokenize` stream and deterministic character-preserving pattern transforms (Rules R1–R12).
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# ADR-0002: Linguistic Sourcing & Keyword Reconciliation
|
|
2
2
|
|
|
3
3
|
## Status
|
|
4
|
-
Accepted (Sprint 1–2)
|
|
4
|
+
Accepted (Sprint 1–2). Tier lists corrected 2026-09-12 to match GRAMMAR.md v1.1
|
|
5
|
+
(`tryna` is Tier A, `chill` Tier B); re-audited with sources open — see
|
|
6
|
+
`hoodscript/docs/linguistics.md` "Sourcing audit — 2026-09-12".
|
|
5
7
|
|
|
6
8
|
## Context
|
|
7
9
|
The Sprint 0 prototype inherited a set of keywords (`cook`, `serve`, `crew`, `Facts`,
|
|
@@ -18,10 +20,14 @@ A rigorous audit against published AAVE lexicography revealed that:
|
|
|
18
20
|
We adopted the 7-step Lexical Sourcing Policy (`hoodscript/docs/lexical-sourcing.md`)
|
|
19
21
|
and reconciled the keywords to authentic, documented AAVE grammar and lexicon:
|
|
20
22
|
* **Tier A Grammatical Features:** Habitual *be* (`be ... in`), intensive continuative
|
|
21
|
-
*steady* (`steady:`), immediate future *finna*, completive *done*,
|
|
22
|
-
*
|
|
23
|
-
|
|
24
|
-
* **Tier
|
|
23
|
+
*steady* (`steady:`), immediate future *finna*, completive *done*, remote past *BIN*,
|
|
24
|
+
negation *ain't* / *ain't nobody*, existential *it's*, and *tryna* — each with a Yale
|
|
25
|
+
Grammatical Diversity Project page.
|
|
26
|
+
* **Tier B Lexical Keywords:** `bet` (agreement/commitment), `dip` (leave/return),
|
|
27
|
+
`fam` (class/family), `no cap` (true), `cap` (false), `holla` (print), `chill` (pass),
|
|
28
|
+
and the `*Trip` exception suffix — each with dictionary attestation of AAVE use.
|
|
29
|
+
* **Tier C Plain English, kept deliberately:** `catch`, `regardless`, `throw`, `skip`, `ask`,
|
|
30
|
+
`else if` — labelled as plain English, never claimed as AAVE.
|
|
25
31
|
* **Python Pass-through:** Where no cited AAVE word existed with verifiable pedigree
|
|
26
32
|
prior to 2005, Python's standard keywords (`if`, `else`, `while`, `import`, `with`)
|
|
27
33
|
pass through unchanged rather than inventing artificial slang.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# hoodlib — the small standard library
|
|
2
|
+
|
|
3
|
+
`hoodlib` ships with HoodScript and holds only what Python's own library
|
|
4
|
+
doesn't give you in one call. Everything in it is standard-library Python,
|
|
5
|
+
importable from `.hs` or `.py`, with no dependencies. Errors are the plain
|
|
6
|
+
Python exceptions the crash reporter already explains.
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
from hoodlib import chart, disk
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## `hoodlib.chart` — plots that fit in a terminal
|
|
13
|
+
|
|
14
|
+
Every function returns a string, so you decide whether to `holla` it, log it,
|
|
15
|
+
or test it.
|
|
16
|
+
|
|
17
|
+
### Sparklines
|
|
18
|
+
|
|
19
|
+
Two points per character on a four-dot Braille scale (80 columns show 160
|
|
20
|
+
points), or one ▁▂▃ block per point with `style="blocks"`. The minimum still
|
|
21
|
+
shows one dot, so every point is visible.
|
|
22
|
+
|
|
23
|
+
```hood
|
|
24
|
+
from hoodlib import chart
|
|
25
|
+
temps = [61, 64, 70, 75, 73, 68, 62]
|
|
26
|
+
holla chart.sparkline(temps, style="blocks")
|
|
27
|
+
holla chart.sparkline(temps)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
▁▃▅█▇▅▁
|
|
32
|
+
⣠⣾⣷⡀
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`width=N` caps the output at N characters by resampling, never by cutting.
|
|
36
|
+
|
|
37
|
+
### Bar charts
|
|
38
|
+
|
|
39
|
+
```hood
|
|
40
|
+
from hoodlib import chart
|
|
41
|
+
holla chart.bar_chart({"corn": 12, "beans": 6, "hay": 0}, title="Bag", width=32)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
Bag
|
|
46
|
+
────────────────────────────────
|
|
47
|
+
corn │█████████████████████ 12
|
|
48
|
+
beans │██████████ 6
|
|
49
|
+
hay │ 0
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Bars scale to the largest value. `sort=True` orders them, `color=True` adds
|
|
53
|
+
plain ANSI colour, and negative values draw an empty bar with the number
|
|
54
|
+
rather than pretending to be zero. `chart.show_bag(bot.bag)` is the same
|
|
55
|
+
thing for a game inventory, and an empty bag is a line saying so.
|
|
56
|
+
|
|
57
|
+
### Histograms
|
|
58
|
+
|
|
59
|
+
```hood
|
|
60
|
+
from hoodlib import chart
|
|
61
|
+
scores = [55, 62, 68, 71, 74, 75, 78, 81, 85, 93]
|
|
62
|
+
holla chart.histogram(scores, bins=4, width=32)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
55–64.50 │██████████ 2
|
|
67
|
+
64.50–74 │██████████ 2
|
|
68
|
+
74–83.50 │███████████████████ 4
|
|
69
|
+
83.50–93 │██████████ 2
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### What goes wrong, in plain English
|
|
73
|
+
|
|
74
|
+
```hood
|
|
75
|
+
# expect-crash
|
|
76
|
+
from hoodlib import chart
|
|
77
|
+
holla chart.sparkline([])
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The report is a `BadValueTrip` saying `sparkline() got an empty series;
|
|
81
|
+
there is nothing to plot`. A non-number names the item: `item 1 is 'x'
|
|
82
|
+
(str)`.
|
|
83
|
+
|
|
84
|
+
## `hoodlib.disk` — files that can't half-write
|
|
85
|
+
|
|
86
|
+
Atomic writes (temp file + fsync + rename), per-path locks so two threads
|
|
87
|
+
can't tear a file, and timestamped backups.
|
|
88
|
+
|
|
89
|
+
```hood
|
|
90
|
+
from hoodlib import disk
|
|
91
|
+
disk.write_json("scores.json", {"ali": 3, "bo": 5})
|
|
92
|
+
holla disk.read_json("scores.json")
|
|
93
|
+
disk.append_csv("log.csv", ["ali", 3])
|
|
94
|
+
holla disk.read_csv("log.csv", header=False)
|
|
95
|
+
holla disk.read_json("missing.json", default={})
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
{'ali': 3, 'bo': 5}
|
|
100
|
+
[['ali', '3']]
|
|
101
|
+
{}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`disk.backup(path, keep=5)` copies `path` to `path.<timestamp>.bak` and
|
|
105
|
+
prunes older copies. A missing file with no `default` is a `MissingFileTrip`.
|
|
@@ -61,6 +61,9 @@ packages = ["src/hoodscript", "src/hoodlib", "src/hoodfarm", "src/hoodarcade"]
|
|
|
61
61
|
"docs/curriculum.md" = "hoodscript/data/curriculum.md"
|
|
62
62
|
# `import vibe` — the Zen of HoodScript, like `import this`.
|
|
63
63
|
"src/vibe.py" = "vibe.py"
|
|
64
|
+
# `hoodfarm test` / `hoodarcade test` benchmark the reference solutions; a pip
|
|
65
|
+
# install has no examples/ tree, so ship them (found via hoodscript/data/solutions).
|
|
66
|
+
"examples/solutions" = "hoodscript/data/solutions"
|
|
64
67
|
|
|
65
68
|
[tool.hatch.build.targets.sdist]
|
|
66
69
|
# The nested hoodscript/ prototype is reference material, not part of the distribution.
|