henriquefy 0.0.1__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 (33) hide show
  1. henriquefy-0.0.1/.gitignore +16 -0
  2. henriquefy-0.0.1/LICENSE +21 -0
  3. henriquefy-0.0.1/NOTICE.md +24 -0
  4. henriquefy-0.0.1/PKG-INFO +40 -0
  5. henriquefy-0.0.1/PLAN.md +475 -0
  6. henriquefy-0.0.1/README.md +17 -0
  7. henriquefy-0.0.1/kb/INDEX.md +14 -0
  8. henriquefy-0.0.1/kb/LICENSE +12 -0
  9. henriquefy-0.0.1/kb/courses/README.md +12 -0
  10. henriquefy-0.0.1/kb/courses/design-api-na-pratica.md +1658 -0
  11. henriquefy-0.0.1/kb/courses/oo-na-pratica.md +2158 -0
  12. henriquefy-0.0.1/kb/glossary.md +3 -0
  13. henriquefy-0.0.1/kb/principles/_template.md +30 -0
  14. henriquefy-0.0.1/kb/principles/deixe-o-codigo-descansar.md +48 -0
  15. henriquefy-0.0.1/kb/principles/prefira-excecoes-a-booleanos.md +77 -0
  16. henriquefy-0.0.1/kb/quotes.md +3 -0
  17. henriquefy-0.0.1/pyproject.toml +64 -0
  18. henriquefy-0.0.1/skills/henrique-ingest/SKILL.md +11 -0
  19. henriquefy-0.0.1/skills/henrique-watch/SKILL.md +10 -0
  20. henriquefy-0.0.1/skills/henriquefy/SKILL.md +43 -0
  21. henriquefy-0.0.1/skills/henriquefy/scripts/henriquefy.sh +14 -0
  22. henriquefy-0.0.1/src/henriquefy/__init__.py +8 -0
  23. henriquefy-0.0.1/src/henriquefy/check/__init__.py +0 -0
  24. henriquefy-0.0.1/src/henriquefy/cli.py +58 -0
  25. henriquefy-0.0.1/src/henriquefy/grade/__init__.py +0 -0
  26. henriquefy-0.0.1/src/henriquefy/ingest/__init__.py +0 -0
  27. henriquefy-0.0.1/src/henriquefy/ingest/html_to_md.py +197 -0
  28. henriquefy-0.0.1/src/henriquefy/install.py +44 -0
  29. henriquefy-0.0.1/src/henriquefy/paths.py +34 -0
  30. henriquefy-0.0.1/state/playlists.json +33 -0
  31. henriquefy-0.0.1/tests/test_install.py +55 -0
  32. henriquefy-0.0.1/tests/test_kb.py +62 -0
  33. henriquefy-0.0.1/tests/test_paths.py +7 -0
@@ -0,0 +1,16 @@
1
+ # local sources: never committed (transcripts, clones, the digests' originals)
2
+ sources/
3
+ # per-user and tool state
4
+ .henriquefy/
5
+ .claude/
6
+ .serena/
7
+ .orca/
8
+ # python
9
+ .venv/
10
+ __pycache__/
11
+ *.pyc
12
+ dist/
13
+ build/
14
+ *.egg-info/
15
+ .pytest_cache/
16
+ .ruff_cache/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ivan Neto
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,24 @@
1
+ # Notice
2
+
3
+ **Independent project.** henriquefy is not affiliated with, maintained by, or endorsed by
4
+ Henrique Bastos or HB Network. The ideas it encodes are his; the encoding, the tooling and any
5
+ mistakes are ours. Watch the originals: https://www.youtube.com/@hbnetworkoficial and
6
+ https://github.com/henriquebastos.
7
+
8
+ **Permission.** Henrique Bastos told Ivan Neto, before 2026-10-08, that this project may be
9
+ published. The course digests under `kb/courses/` are published on that basis, all rights
10
+ reserved, until he confirms a license in writing.
11
+
12
+ **Licenses.** Code: MIT (`LICENSE`). Knowledge-base prose we wrote: CC BY 4.0 (`kb/LICENSE`),
13
+ excluding `kb/courses/` as above. Code excerpts keep the license of the repository they come from,
14
+ recorded per excerpt; `monopoly`, `eventex` and `pacote-desafios-pythonicos` have no license file
15
+ (checked 2026-10-08), and `gnucash-to-beancount`, `itauscraper`, `dcache` and `chipy8` are
16
+ copyleft or BSD-4-Clause, so excerpts from those seven are quotation-length only.
17
+
18
+ **How the digests were made.** Ivan Neto built the two course digests (`oo-na-pratica`,
19
+ `design-api-na-pratica`) from the automatic transcripts of the playlists plus the public code,
20
+ as HTML printed to PDF in September 2026. Quotes were captured from those transcripts and not
21
+ checked against the video, so every quote carries `verified: false`.
22
+
23
+ **Captions.** The ingest pipeline fetches YouTube automatic captions with yt-dlp for local
24
+ distillation only. Raw captions and transcripts are never committed or redistributed.
@@ -0,0 +1,40 @@
1
+ Metadata-Version: 2.5
2
+ Name: henriquefy
3
+ Version: 0.0.1
4
+ Summary: Claude Code skills that apply Henrique Bastos's Python, OO, API-design and testing practices to your code: ask, check, grade, transform.
5
+ Project-URL: Homepage, https://github.com/ivancrneto/henriquefy
6
+ Project-URL: Repository, https://github.com/ivancrneto/henriquefy
7
+ Project-URL: Issues, https://github.com/ivancrneto/henriquefy/issues
8
+ Author-email: Ivan Neto <ivan.cr.neto@gmail.com>
9
+ License-Expression: MIT AND CC-BY-4.0
10
+ License-File: LICENSE
11
+ License-File: NOTICE.md
12
+ License-File: kb/LICENSE
13
+ Keywords: claude-code,code-quality,henrique-bastos,python,skills
14
+ Classifier: Development Status :: 2 - Pre-Alpha
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Software Development :: Quality Assurance
21
+ Requires-Python: >=3.12
22
+ Description-Content-Type: text/markdown
23
+
24
+ # henriquefy
25
+
26
+ Claude Code skills that know how [Henrique Bastos](https://github.com/henriquebastos) (HB Network)
27
+ writes Python, designs APIs, models objects and tests, and that apply it to your code.
28
+
29
+ ```
30
+ uvx henriquefy install # writes the henriquefy skill into ~/.claude/skills/
31
+ ```
32
+
33
+ Then, in Claude Code: `/henriquefy`, or just ask "what would Henrique do here?".
34
+
35
+ Status: Phase 0. The `ask` mode is live with a two-principle knowledge base; `check`, `grade` and
36
+ `transform` follow. The full plan is in [PLAN.md](PLAN.md).
37
+
38
+ Independent project, not affiliated with or endorsed by Henrique Bastos or HB Network; published
39
+ with his permission. See [NOTICE.md](NOTICE.md). Code is MIT; knowledge-base prose is CC BY 4.0
40
+ except the course digests.
@@ -0,0 +1,475 @@
1
+ # henriquefy Plan
2
+
3
+ Goal: a set of Claude Code skills that know how Henrique Bastos (HB Network) writes Python,
4
+ designs APIs, models objects, tests, and thinks about a developer career, and that can
5
+ **apply** that knowledge to any codebase: explain, check, grade, and transform.
6
+
7
+ Status (2026-10-08): repo has two course digests, `oo-na-pratica` (121 PDF pages) and
8
+ `design-api-na-pratica` (56), as HTML plus a browser-printed PDF of each. Ivan built them from
9
+ transcripts of the two playlists; their quotes were not checked against the video, so they carry
10
+ `verified: false`. Nothing else yet. No commits.
11
+
12
+ ## 1. Shape of the system
13
+
14
+ Three concerns, three skills, one shared knowledge base (KB). Skills are thin; the KB is the product.
15
+
16
+ | Piece | Role | Who runs it |
17
+ |---|---|---|
18
+ | `kb/` | The distilled knowledge: principles, patterns, rubric, course and repo digests, quotes, glossary | Read by every skill |
19
+ | `skills/henriquefy` | Consumer. Applies the KB to code: `ask`, `check`, `grade`, `transform` | You, on any repo |
20
+ | `skills/henrique-ingest` | Producer. Turns a source (video, playlist, PDF, repo) into KB entries with citations | You, when a new source appears |
21
+ | `skills/henrique-watch` | Monitor. Detects new videos, repos, commits; queues them for ingest | Scheduled: cron or launchd on the maintainer's machine, or any agent scheduler |
22
+
23
+ Why split: ingest is slow, token-heavy, and run rarely. henriquefy must be fast and load only
24
+ what a task needs (progressive disclosure: short `SKILL.md`, details in `references/`).
25
+
26
+ ### Repo layout
27
+
28
+ Published as the `henriquefy` package on PyPI (name free as of 2026-10-08). One package, one
29
+ CLI, three skills shipped as package data.
30
+
31
+ ```
32
+ henriquefy/
33
+ ├── PLAN.md
34
+ ├── README.md
35
+ ├── LICENSE # MIT; kb/LICENSE is CC BY 4.0 except kb/courses/ (see "Public repo")
36
+ ├── NOTICE.md # non-affiliation note, Henrique's OK, licensing facts per repo, YouTube terms note on caption fetching
37
+ ├── pyproject.toml # name henriquefy, src layout, [project.scripts] henriquefy = "henriquefy.cli:main"
38
+ ├── src/henriquefy/
39
+ │ ├── cli.py # install | update | check | grade | ingest | watch
40
+ │ ├── check/ # AST rules, one module per rule family, each rule -> principle id
41
+ │ ├── grade/ # rubric loader, aggregation, report.py renders report.md and the JSON
42
+ │ ├── ingest/ # html_to_md, yt_fetch, gh_fetch, distill prompts, build_index
43
+ │ ├── watch.py
44
+ │ └── paths.py # importlib.resources access to kb/, skills/ and state/
45
+ ├── kb/ # knowledge base, shipped into the wheel via hatch force-include
46
+ │ ├── INDEX.md
47
+ │ ├── principles/ patterns/ courses/ repos/ career/
48
+ │ ├── rubric.md check-rules.md # generated by build_index.py: weights per dimension; rule id -> principle id
49
+ │ └── glossary.md quotes.md
50
+ ├── skills/ # shipped into the wheel the same way
51
+ │ ├── henriquefy/SKILL.md + references/ (transform-playbook.md; kb/ is copied here at install) + scripts/
52
+ │ ├── henrique-ingest/SKILL.md + prompts/ (distill-transcript.md, distill-repo.md)
53
+ │ └── henrique-watch/SKILL.md
54
+ ├── state/ # playlists.json seed, force-included into the wheel like kb/; per-user state lives in ~/.henriquefy/ (state/, rubric.toml, ignore.toml)
55
+ ├── evals/ # ask.md, fixtures/, transform/, calibration/ (his.json, alumni.json)
56
+ ├── sources/ # local only, gitignored: html/, pdf/, transcripts/, repos/ (with manifest.json)
57
+ └── .github/workflows/ # ci.yml (ruff, pytest, evals), release.yml (uv build + trusted publishing on tag)
58
+ ```
59
+
60
+ `kb/` and `skills/` stay at the repo root so they read well on GitHub; the wheel includes them
61
+ under `henriquefy/kb` and `henriquefy/skills`. `paths.py` tries
62
+ `importlib.resources.files("henriquefy") / "kb"` and falls back to the repo root, because an
63
+ editable install (`uv run`) resolves the package to `src/henriquefy/`, which has no `kb/`.
64
+
65
+ ### Distribution
66
+
67
+ ```
68
+ uvx henriquefy install # writes the self-contained henriquefy skill into ~/.claude/skills/
69
+ uvx henriquefy install --project # into ./.claude/skills/ of the current repo instead
70
+ uvx henriquefy install --all # also installs henrique-ingest and henrique-watch (maintainer use)
71
+ uvx henriquefy@latest update # the only command that pins @latest: re-installs the skill, keeps ~/.henriquefy/
72
+ uvx henriquefy check path/ # mechanical rules only, no Claude needed, JSON or text
73
+ uvx henriquefy grade path/ # Nota mecânica: deterministic, from mechanical findings only
74
+ uvx henriquefy ingest <source> # fetch + prepare; distillation prompts are printed for the agent
75
+ uvx henriquefy watch # diff YouTube and GitHub against ~/.henriquefy/state
76
+ ```
77
+
78
+ `install` writes each skill as `SKILL.md` + `references/` + `scripts/`, copies the KB into
79
+ `references/kb/` of the `henriquefy` skill only, and replaces the skill directory wholesale. User
80
+ files live in `~/.henriquefy/` (`rubric.toml`, `ignore.toml`, `state/`), which `install` and
81
+ `update` never touch; when a rubric override is active the report prints "rubric overrides
82
+ active" with the overridden keys, and calibration and exit criteria run with none. The installed
83
+ skill never points into site-packages, because the uvx environment is a cache uv may prune. Its
84
+ scripts call `uvx henriquefy==X ...` with the version `install` wrote, so skill and CLI never
85
+ diverge; uvx contacts the index on every run and fails without network unless `--offline` (uv
86
+ 0.11.32), so the scripts try `--offline` first and retry without it on a cold cache. With no cache
87
+ and no network the script prints one line, `henriquefy X not cached; connect once or run uvx
88
+ henriquefy@latest update`, and exits non-zero. `uv tool install henriquefy` gives a fixed binary
89
+ on PATH instead. `install` writes the version as
90
+ `metadata: {henriquefy_version: X}`, the one frontmatter key the Agent Skills spec leaves free;
91
+ any other custom key fails skill packaging. `SKILL.md` stays under 100 lines and never inlines KB
92
+ content; it points at `references/kb/INDEX.md`. Only `henriquefy` is installed by default,
93
+ because Claude Code loads every installed skill's frontmatter into every session.
94
+ `install --project` puts the KB copy under the target repo's git and says so.
95
+
96
+ Version policy: the KB is content, so every KB change is a release. Patch for fixes and new
97
+ quotes, minor for new principles or courses, major for rubric changes that move grades.
98
+ Releases: tag `vX.Y.Z`; `release.yml` runs `uv build` and `uv publish` with trusted publishing
99
+ (`permissions: id-token: write`) to TestPyPI (needs a `[[tool.uv.index]]` with `publish-url`) and
100
+ then PyPI. Each index needs a pending publisher, registered by Ivan in the browser before the first
101
+ tag, with the exact GitHub repo name, the workflow filename `release.yml` and the environment
102
+ name the job uses. No tokens in the repo.
103
+
104
+ Later, not now: a Claude Code plugin manifest for marketplace install, and `install --target`
105
+ for other agents (Henrique himself uses pi and codex).
106
+
107
+ ### Public repo
108
+
109
+ - Transcripts and clones of his repos are never committed; `kb/` holds digests, short cited
110
+ quotes and excerpts. The two digests are Ivan's; the committed form is their markdown
111
+ conversion under `kb/courses/`, and the PDFs move to gitignored `sources/pdf/`.
112
+ - README states plainly: independent project, not affiliated with or endorsed by Henrique Bastos
113
+ or HB Network, credit for the ideas to him, links to the channel and repos. Henrique OK'd
114
+ publishing (confirmed by Ivan, 2026-10-08); `NOTICE.md` records the date and medium.
115
+ - MIT for the code (`LICENSE`). CC BY 4.0 for `kb/` prose we wrote: principles, patterns, repo and
116
+ career notes (`kb/LICENSE`). The course digests under `kb/courses/` carry no license for now:
117
+ they derive from his lectures, so they are published with his permission, all rights reserved,
118
+ until he confirms a license in writing; `NOTICE.md` and `kb/courses/README.md` say so, and
119
+ pyproject's `license = "MIT AND CC-BY-4.0"` is accompanied by that exclusion in `NOTICE.md`.
120
+ Quotes are his, brief and cited. Code excerpts follow the repo license; `monopoly`, `eventex`,
121
+ `pacote-desafios-pythonicos` have none (checked 2026-10-08), and `gnucash-to-beancount`,
122
+ `itauscraper`, `dcache`, `chipy8` are copyleft or BSD-4-Clause: excerpts from all seven stay
123
+ quotation-length with path and commit; Ivan will ask him to add MIT to the three.
124
+ - Alumni repos: naming a public, self-described course reimplementation as a reference is fine
125
+ (the API digest names `virb30/design-api` and `HenriqueCCdA/Design_de_API_na_pratica`; `kb/`
126
+ may link such repos as "see also"). Grading, ranking or excerpting a student's repo in public
127
+ is not: no alumni code in `kb/` (forks inherit the missing licenses above; the two
128
+ reimplementations are unlicensed), no per-repo score or rank in reports or committed data, no
129
+ alumni repo named as a bad example. Alumni repos are read locally; a recurring mistake becomes
130
+ a rule plus a synthetic fixture, and `alumni.json` keys scores by random id (never a hash of the name), with the
131
+ id-to-repo map in gitignored `sources/`.
132
+
133
+ ## 2. Knowledge base design
134
+
135
+ ### Principle file (the atomic unit)
136
+
137
+ ```markdown
138
+ ---
139
+ id: exceptions-over-booleans
140
+ title: Prefira exceções específicas a booleanos e if
141
+ category: errors # modeling | simplicity | errors | testing | api | project | readability | career
142
+ weight: 3 # 1-5, feeds the rubric
143
+ detectable: partial # mechanical | partial | judgment
144
+ era: timeless # timeless | 2010s | 2020s | 2026; only tooling principles are dated
145
+ scope: python # python | api | web | project | career; never a framework name
146
+ sources:
147
+ - type: course
148
+ course: oo-na-pratica
149
+ lesson: null # set only when the section is a per-lesson one; section 12 is cross-cutting
150
+ section: "12.9" # section of kb/courses/oo-na-pratica.md, which keeps the PDF numbering; the PDF itself is gitignored
151
+ timestamp: null # hh:mm:ss in the lesson video when the source is a transcript
152
+ - type: repo
153
+ class: his # his | course | alumni (see "Code sources"); alumni never appears in a principle
154
+ repo: henriquebastos/monopoly
155
+ path: game.py
156
+ commit: <sha> # files move; a citation without a commit goes stale
157
+ ---
158
+ **Rule.** One-paragraph statement in English.
159
+
160
+ **Why Henrique says so.** The reasoning, in his terms. Verbatim quote in Portuguese, or a timestamped paraphrase marked `verified: false`.
161
+
162
+ **Looks like.** Good example (from his repo when possible). Bad example.
163
+
164
+ **How to detect.** Signals a checker can use. Rule ids in `kb/check-rules.md`.
165
+
166
+ **How to fix.** The refactor, step by step, in his order.
167
+ ```
168
+
169
+ Every claim carries a citation (course, lesson and section or timestamp; or repo, path and commit). No citation, no entry.
170
+ `kb/INDEX.md` is what the skill reads first: one line per principle and per pattern (id,
171
+ category, one-sentence rule), no prose, at most 200 lines; `build_index.py` fails above that.
172
+
173
+ ### Framework coverage: Django and FastAPI
174
+
175
+ Henrique teaches on Django, but the KB must serve FastAPI equally. A principle never names a
176
+ framework; frameworks appear only in `kb/patterns/`, one section per framework:
177
+
178
+ ```markdown
179
+ ---
180
+ id: exception-to-http-middleware
181
+ principle: errors-at-the-boundary
182
+ frameworks:
183
+ django: {origin: his, course: design-api-na-pratica, lesson: 6, section: "<n>"}
184
+ fastapi: {origin: his, repo: henriquebastos/hamsterdan, path: src/hamsterdan/host/api.py, commit: <sha>}
185
+ ---
186
+ ```
187
+
188
+ `origin` is `his` for code from his repos or lessons and `translated` for a rendition we wrote by
189
+ applying his principle to a framework he did not show. There is no `alumni` origin: a
190
+ reimplementation may be linked under "see also", never supply the rendition. Findings and
191
+ reports carry the flag, so a FastAPI finding backed by a translated pattern says so.
192
+
193
+ His FastAPI and Starlette code: `hamsterdan` (2026, host API) and `petrus`; both pydantic-heavy,
194
+ like `beans`, `jira-genie` and `python-jsonstar`. So for FastAPI the 2026 default for models and
195
+ serialization is pydantic (Django keeps its models and forms); `python-decouple` for config applies to both.
196
+
197
+ Translation plan, Django to FastAPI: the `allow` method decorator becomes per-method route
198
+ decorators; the exception middleware becomes `app.exception_handler`; `HTTPStatus`, the service
199
+ layer and HATEOAS links by state stay; the Django test client becomes `TestClient`; forms and
200
+ models become pydantic schemas plus the project's persistence. One pattern file each, with both
201
+ renditions and a fixture per framework; Phase 1 writes the three the fixtures need, Phase 3 the rest.
202
+
203
+ ### What we already have (from the PDFs)
204
+
205
+ OO na Prática, section 12, gives ten principles outright; they become the ten Phase 1 principle files:
206
+ 1. Deixe o código descansar. 2. Não projete a generalização, deixe o código pedi-la.
207
+ 3. Escolha a regra mais simples. 4. Postergue decisões enquanto o entendimento cresce.
208
+ 5. Pense localmente, nunca globalmente. 6. Uma responsabilidade por identidade.
209
+ 7. Evite ciclos; busque a árvore. 8. Componha em vez de herdar, quando puder.
210
+ 9. Prefira exceções específicas a booleanos e if (the template above). 10. O código é a interface.
211
+
212
+ Design de API na Prática gives: the four pillars (interface, resource, representation,
213
+ identifier), Richardson maturity levels 0 to 3, `HTTPStatus` over magic numbers, decorators with
214
+ `functools.wraps`, exception-to-HTTP middleware, verb semantics, HATEOAS as a state machine,
215
+ service layer, money representation in JSON, pragmatism over purity. Plus the pedagogy itself:
216
+ "content pulled by the student's need, not pushed by preconception".
217
+
218
+ ### Code sources: three classes, three trust levels
219
+
220
+ | Class | What | Trust | Used for |
221
+ |---|---|---|---|
222
+ | `his` | Henrique's 61 public repos, course-related or not, and the HBNetwork org (python-decouple, pds-*, coding-dojo, django-ultratenant, django-custom-permissions, dcache, python-eduzz) | ground truth | principles, patterns, calibration |
223
+ | `course` | Code written live in a lesson, recovered from transcript or from a PDF's line-by-line section | ground truth, dated to the lesson | patterns with lesson citations |
224
+ | `alumni` | Students' and community reimplementations of his courses: `virb30/design-api`, `HenriqueCCdA/Design_de_API_na_pratica` (both named in the API PDF, section 14.2), the 9 forks of `eventex` plus eventex-style repos found by search (a few hundred candidates, mostly noise), the 224 forks of pacote-desafios-pythonicos, pds-* forks | evidence, never ground truth; read locally, may be linked as a reference, never excerpted, scored or ranked in public (see "Public repo") | calibration spread, mistake rules with synthetic fixtures |
225
+
226
+ Every KB entry and code excerpt carries its class in frontmatter; the report never cites an
227
+ alumni repo as "Henrique does this". Alumni code shows how the principles land for others,
228
+ supplies realistic mistakes for rules and fixtures, and gives a like-for-like rubric check:
229
+ `eventex` and `pacote-desafios-pythonicos` against their own forks, the original expected at or
230
+ above the fork median on every timeless dimension.
231
+
232
+ His repos outside the courses count fully (requests-pro, python-jsonstar, python-decouple, the 2012
233
+ libraries, the 2026 agent-era repos): how he writes when nobody is watching is the style to reproduce.
234
+
235
+ ### Repos worth mining first (from `gh api`, 61 public repos)
236
+
237
+ | Repo | Why | Era |
238
+ |---|---|---|
239
+ | `monopoly` | The OO course's codebase. TDD, CRC modeling, Monte Carlo | 2022 |
240
+ | `requests-pro` | Mature API client: auth, retry, encoders, error handling, audit | 2026 |
241
+ | `python-jsonstar` | Small, focused library. Packaging and extension design | 2025 |
242
+ | `HBNetwork/python-decouple` | Config vs code. His most used project | ongoing |
243
+ | `pacote-desafios-pythonicos` | Idiomatic Python exercises | 2023 |
244
+ | `eventex` | Django app in his style (Welcome to the Django) | 2015, pushed 2023 |
245
+ | `hamsterdan` | His FastAPI code, plus `docs/process/engineering-conventions.md`, `AGENTS.md`, `tests/test_architecture.py`, `audit-rules/`. He wrote his own rules down; mine this first | 2026 |
246
+ | `beans`, `jira-genie`, `petrus-engine`, `petrus` | Current practice with AI agents, CLI, Petri nets, Starlette, pydantic | 2026 |
247
+ | `django-aggregate-if`, `django-test-without-migrations`, `sqlformatter` | Classic Django-era libraries | 2012-2015 |
248
+
249
+ ### Sources that need the ingest pipeline
250
+
251
+ Channel: HB Network, id `UCEbLV4AfUhoxNb_-Ionw83g`, 41 playlists (enumerated 2026-10-08 with
252
+ `yt-dlp --flat-playlist`). Auto captions spot-checked as available in `pt-orig`, `pt` and `en`,
253
+ formats json3/vtt/srt; no human subtitles. Prefer `pt-orig`, fall back to `pt`, and have
254
+ `yt_fetch.py` log and skip a video with neither instead of failing the playlist.
255
+
256
+ Ingest priority, by relevance to the four skill modes and by cost in hours of video:
257
+
258
+ | Tier | Playlist | id | Videos | Hours | Feeds |
259
+ |---|---|---|---|---|---|
260
+ | done | Orientação a Objetos na Prática | `PLeKXYyZCJHxemNCYYvDUw0wRsMiN7aX1m` | 23 | 8.0 | modeling, simplicity, testing |
261
+ | done | Design de API na Prática | `PLeKXYyZCJHxdD1CXDeEymwI1S9wlcsmYo` | 9 | 24.0 | api, errors, project |
262
+ | 1 | Refatoração na Prática | `PLeKXYyZCJHxfTqEvicb9dqcbj-eCOFhhj` | 34 | 4.0 | transform, check |
263
+ | 1 | Transforme seu código Procedural em OO | `PLeKXYyZCJHxeKQ13fuBUuLyfeOK9Jr8t7` | 10 | 3.3 | transform, modeling |
264
+ | 1 | Raio-X do Test-Driven Development | `PLeKXYyZCJHxe1X_B-o5bMDyNLxIBQB1q7` | 5 | 2.3 | testing |
265
+ | 1 | Raio-X da Orientação a Objetos | `PLeKXYyZCJHxdT8vUW3x9bd7B8PnwnHINW` | 5 | 0.7 | modeling |
266
+ | 1 | Dicas de Programação | `PLeKXYyZCJHxdnGoV8TBYzKqsm8p3PIEeQ` | 53 | 2.6 | check rules (short, dense) |
267
+ | 2 | Domine o Método da Refatoração Rápida | `PLeKXYyZCJHxfHUETjNouzr1hyaiuljrUY` | 16 | 4.6 | transform |
268
+ | 2 | Refatoração com POO em código legado | `PLeKXYyZCJHxeEeta6ddgqUagLp_Oo_kAx` | 9 | 1.5 | transform |
269
+ | 2 | Superando o Labirinto dos Testes | `PLeKXYyZCJHxfGaSISKQtt4we_3wmuZEzg` | 8 | 2.2 | testing |
270
+ | 2 | Pacote de Desafios Pythônicos | `PLeKXYyZCJHxetT2NwFzKcslYfiE3yPUWL` | 15 | 0.9 | readability, idioms (repo exists) |
271
+ | 2 | Publique sua Biblioteca Python do zero | `PLeKXYyZCJHxeM2DehynN89gk1apr1EwQz` | 5 | 0.8 | project, packaging |
272
+ | 2 | O Ambiente Python Perfeito | `PLeKXYyZCJHxerM2W71_WeWLuvU-O22vUj` | 5 | 0.9 | project |
273
+ | 2 | Evolução constante de código usando Kata | `PLeKXYyZCJHxdxmtm_Kclt_NMvrWLasxgF` | 5 | 0.6 | testing, practice |
274
+ | 3 | Welcome to the Django | `PLeKXYyZCJHxczQsE7L5H9RXTcNFjx3U55` | 121 | 32.8 | django, project (pair with `eventex`) |
275
+ | career 1 | Caminho da Autonomia | `PLeKXYyZCJHxcCf96DZdrCwJmZj7cEilus` | 8 | 3.8 | career: his core thesis on developer autonomy |
276
+ | career 1 | Workshop: Torne-se protagonista da sua carreira na programação | `PLeKXYyZCJHxdeXekJnaSPKtjzL_2Wpwqx` | 3 | 0.4 | career: short, same thesis |
277
+ | career 2 | Método para Cumprir Qualquer Prazo | `PLeKXYyZCJHxfpAJAR9q27VTugkNvHMjgP` | 7 | 2.2 | work method: estimation, delivery |
278
+ | career 2 | Método para Programar do Jeito Fácil | `PLeKXYyZCJHxf6DOZXFVBRVyNFf3WPAu3e` | 6 | 0.8 | work method |
279
+ | career 2 | O método rápido para aprender um framework novo | `PLeKXYyZCJHxdDXilIsPrEZBQ0AOwyHBgg` | 7 | 2.0 | work method: learning |
280
+ | career 2 | Desmistificando o Desenvolvimento Ágil | `PLeKXYyZCJHxfeseMJ8JCE9J7qEjsWvoNI` | 7 | 1.9 | work method: process |
281
+ | career 3 | Carreira e Empreendedorismo | `PLeKXYyZCJHxe22wb--3Y4x8IH3AVSlbys` | 22 | 1.1 | career: short clips, broad |
282
+ | career 3 | Mercado de TI | `PLeKXYyZCJHxcw7CmT_RRw3eY0fNloEwF1` | 20 | 1.0 | career: market |
283
+ | career 3 | Visão Estratégica | `PLeKXYyZCJHxe2kDCsM9N44dLxXvgNksGe` | 32 | 2.7 | career: strategy |
284
+ | career 4 | Calculando o Valor que Você Gera | `PLeKXYyZCJHxcyBcjqbmrmX_1PdDFzLgel` | 5 | 1.3 | business side: pricing |
285
+ | career 4 | Marketing Pessoal e Vendas | `PLeKXYyZCJHxd51nPK6GELCbi29z9qxI0C` | 7 | 2.3 | business side: selling |
286
+
287
+ Not prioritized: SHOTS, Palestras, Mão na Massa, Regex, Algoritmos, Programação Dinâmica,
288
+ app desktop, SaaS, previdência, Data Science, Porta lógica, depoimentos, and the three long
289
+ workshops for non-programmers (novo normal 9.3 h, sem ser programado 11.1 h, medo de empreender 8.7 h). Revisit after tier 2.
290
+
291
+ Career order (decided 2026-10-08): career 1 is the thesis, career 2 the work methods that also feed
292
+ development practice, career 3 the short broad clips, career 4 the business side. Career ingest
293
+ starts after tier 1 and runs one playlist per session, interleaved with tier 2.
294
+
295
+ Tier 1 is about 13 hours of video and is what `transform` and `check` need most. Welcome to the
296
+ Django mostly teaches Django and waits until the grading of plain Python is calibrated.
297
+
298
+ Design de API has nine lessons of two to three hours each (24 h in the PDF); a three-hour lesson
299
+ transcript is too long to distill with citations in one pass, hence the windows in Phase 4.
300
+
301
+ ## 3. henriquefy modes
302
+
303
+ ### `ask`: "what would Henrique do"
304
+ Input: a question or a code snippet. Output: an answer grounded in the KB, with citations and
305
+ the lesson to watch (playlist and lesson number until Phase 4 stores video ids); the cheapest mode. Every sentence attributed to him carries a principle id
306
+ or a lesson and timestamp. When the KB has no entry, `ask` says so first and marks any further
307
+ advice as its own, never his; a `translated` pattern is named as ours.
308
+
309
+ ### `check`: what to fix and why
310
+ 0. Detect the framework from imports and dependencies (`django`, `fastapi`, `starlette`, neither). Rules load the matching pattern rendition; plain-Python rules always run.
311
+ 1. Run `uvx henriquefy check` on the target (file, dir, or repo). Per-file `ast` rules: magic
312
+ HTTP numbers (integer literals 100 to 599 in status arguments); bare or broad `except`;
313
+ mutable defaults; tests without assertions (a `test_*` function with no `assert`, no call to
314
+ an attribute named `assert*`, which covers `self.assert*` and `mock.assert_called*`, and no
315
+ `pytest.raises` or `pytest.warns` block; known false positive: assertions in a helper, handled
316
+ with the ignore comment); `os.environ` or `os.getenv` only in a project that already depends
317
+ on `python-decouple` in `pyproject.toml` or a requirements file (whether to adopt decouple is
318
+ a judgment finding or the Projeto e config signal; FastAPI projects commonly use
319
+ pydantic-settings); class size thresholds; `return False` inside an `except` handler, the
320
+ only mechanical form of "boolean as error signal" (the rest is judgment in step 2).
321
+ Whole-repo rules needing cross-file import resolution: import cycles, inheritance depth.
322
+ A file `ast.parse` rejects (newer syntax than the running Python) is one finding, never a crash.
323
+ Every rule has a `# henriquefy: ignore[rule-id]` suppression and a clean fixture it must not
324
+ fire on. Output: JSON findings keyed by rule id.
325
+ 2. Claude reads the code plus the matching principle files and adds judgment findings:
326
+ responsibility leaks, generalization designed too early, modeling that fights the domain.
327
+ Scope: the path given; with no path, the files with mechanical findings plus, inside a git
328
+ repo, the files changed in the working tree (outside git, mechanical findings only); `--all`
329
+ reads everything and says how many files that is before starting.
330
+ 3. Report, one line per finding: `path:line`, rule, why (one sentence in Henrique's reasoning), citation, fix.
331
+
332
+ ### `grade`: the Nota Henrique
333
+ Rubric dimensions (weights from principle frontmatter, compiled by `build_index.py`): Modelagem,
334
+ Simplicidade, Erros, Testes, API, Projeto e config, Legibilidade, each 0 to 10 and mapped 1:1 to
335
+ a principle `category`; `career` has no dimension. The API dimension scores Richardson level,
336
+ status codes, verb semantics, error contract and service layer, which read the same in Django and
337
+ FastAPI. A dimension with no evidence in the target (no HTTP layer, no tests) is N/A and left out
338
+ of the overall. Overall score; the letter grade is attached to the Nota do Henrique only, and the Nota mecânica stays a bare number so a lint score is never read as his verdict. A per-dimension "aula para assistir" for the
339
+ weakest area. Repo grade adds structure signals, static only (the target's code never runs): tests
340
+ present, settings via decouple, README, dependency pinning sanity (the OO digest, section 20.3, found
341
+ `monopoly`'s own `pytest==6.1.2` pin broken; the check is honest, not fan-like).
342
+ Two scores, always labeled:
343
+ - **Nota mecânica.** A pure function of the mechanical JSON findings and the weights in
344
+ `rubric.md`: two runs on the same commit give the same number. It is what
345
+ `uvx henriquefy grade` prints, what the JSON trend file stores, and what exit criteria and calibration use.
346
+ Dimensions with a mechanical component: Erros, Testes, API and Projeto e config fully;
347
+ Modelagem and Legibilidade through shape signals only (class size, inheritance depth, mutable
348
+ defaults); Simplicidade none, so it is absent here.
349
+ - **Nota do Henrique.** The full rubric over all seven dimensions, produced only when Claude
350
+ runs `grade` and adds its judgment findings from `check` step 2. Labeled non-deterministic;
351
+ every dimension lists its evidence (finding, file, line, principle id). The judgment
352
+ contribution is unbounded but labeled until the Phase 7 spread data exists.
353
+ Output: stdout by default; `--report` writes `.henriquefy/report.md` in the target repo with both scores, plus JSON holding the
354
+ Nota mecânica for trend across runs.
355
+
356
+ Era policy (decided 2026-10-08): grade strict to his current, 2026 practice by default. `era` on
357
+ principles serves only the `--era` flag (older repos graded against their time, for calibration)
358
+ and the report's tooling-drift note on Projeto e config findings. Modeling, simplicity, errors
359
+ and testing are timeless.
360
+
361
+ Calibration rule, on the Nota mecânica: `requests-pro` (2026) at 8 or above on every scored
362
+ dimension of the default rubric; `monopoly` (2022) at 8 or above on the timeless dimensions, with
363
+ Projeto e config allowed to be low (the OO digest, section 20.3, documents the broken
364
+ `pytest==6.1.2` pin) and marked as tooling drift; `monopoly` with `--era 2022` is the check for
365
+ the drift logic, and his older repos follow the same pattern. If a timeless dimension of
366
+ `monopoly` scores a 5, read every finding: true findings stay, and the rubric changes only for
367
+ false positives or a weight that contradicts a principle he states. Weights never move to raise
368
+ his score.
369
+
370
+ ### `transform`: rewrite in his style
371
+ Order follows his method, not a lint list:
372
+ 1. `check` first. Pick findings by weight.
373
+ 2. If tests are missing, write characterization tests before touching code (TDD is non-negotiable in the course).
374
+ 3. Propose one change per principle, in his order, running the tests after each; never change
375
+ public behavior. No commits, staging or branches unless asked: the working tree is left
376
+ changed with a note of what a commit per principle would be. Use the project's test runner,
377
+ or add pytest under `tests/` and say so.
378
+ 4. Explain the diff with citations. The explanation is the deliverable. Stop at "deixe o código
379
+ descansar": do not generalize.
380
+
381
+ ## 4. Phases
382
+
383
+ ### Phase 0: Scaffold (1 session)
384
+ - `uv init --package --build-backend hatch` (uv 0.11 defaults to `uv_build`, which has no force-include), src layout, `pyproject.toml` with `[project.scripts] henriquefy = "henriquefy.cli:main"` and `[tool.hatch.build.targets.wheel.force-include]` mapping `kb`, `skills` and `state` to `henriquefy/kb`, `henriquefy/skills` and `henriquefy/state`. `requires-python = ">=3.12"` (decided; his 2026 repos range from 3.10 to 3.14, so `check` runs on `hamsterdan` and `petrus` under `uvx --python 3.14`).
385
+ - `.gitignore`: `sources/transcripts/`, `sources/repos/`, `sources/pdf/`, `.venv`, `.henriquefy/`.
386
+ - `cli.py` with `install` and `--version` only. `uv run henriquefy install` must produce a working skill dir on day one.
387
+ - Skeleton for the three skills: frontmatter with `name` equal to the directory name and `description` carrying the trigger phrases ("what would Henrique do", "nota Henrique", "henriquefy this file"; Claude Code picks a skill by its description, and `/henriquefy` is the skill name), a `SKILL.md` under 100 lines that never inlines KB content, empty `references/`.
388
+ - `kb/INDEX.md` stub, principle template, `evals/` stub, `LICENSE`, `NOTICE.md`, README with the non-affiliation note.
389
+ - `ci.yml` running ruff, pytest and the install smoke test; `release.yml` as described under Distribution.
390
+ - Order (a pending publisher reserves nothing; the name is taken only by the first publish, so tag early): first commit; create the public GitHub repo `henriquefy` under Ivan's account and push; confirm `henriquefy` is still free on TestPyPI and PyPI (both 404 on 2026-10-08); register the pending publisher on each with that repo name, `release.yml` and the environment name; then `uv build` and tag `v0.0.1`, so the empty package reaches TestPyPI and PyPI and proves the pipeline before any content exists.
391
+ - **Exit criterion (CI):** `ci.yml` is green, including an install smoke test that runs `henriquefy install --project` inside a temporary directory and asserts `SKILL.md` with `metadata.henriquefy_version` exists; the `v0.0.1` release job is green on both indexes.
392
+
393
+ ### Phase 1: KB v0 from the two PDFs (2-3 sessions)
394
+ - `html_to_md.py`: convert the two HTML digests (`sources/html/`, gitignored like the PDFs) to `kb/courses/<course>.md`, keeping the `h2` numbering as section ids, tables, `pre` blocks and blockquotes; the HTML is clean (25 and 17 `h2`, no ids, inline CSS only), so no PDF extraction is needed.
395
+ - Distill `oo-na-pratica` into: 10 principle files, `courses/oo-na-pratica.md`, glossary and quotes merged (digest quotes come from transcripts and were not checked against the video, so every one carries `verified: false`), patterns from the line-by-line analysis of the seven `monopoly` modules.
396
+ - Distill `design-api-na-pratica` into: API principles, Richardson pattern files, `courses/design-api-na-pratica.md`. Pattern files get the Django rendition from the course. FastAPI renditions marked `translated` are written only for the patterns that Phase 2 fixtures exercise (status codes, exception handler, verb semantics); the rest wait for Phase 3, where `hamsterdan` supplies `his` renditions.
397
+ - `build_index.py` produces `INDEX.md` and `rubric.md` (and, from Phase 2, `check-rules.md`). Generated files are committed so GitHub and the wheel show them without a build step; CI regenerates them and fails on any diff.
398
+ - **Exit criterion (manual, needs the agent):** `evals/ask.md` holds five questions (three OO, two API) with the expected principle id and citation; the installed skill answers all five with the expected id and a citation that exists in the KB. (CI) a test checks every citation id in `evals/ask.md` exists in `kb/`.
399
+
400
+ ### Phase 2: henriquefy v0, check and grade (2 sessions)
401
+ - `check/` with the first 8 to 10 per-file mechanical rules, each mapped to a principle id; `build_index.py` emits `kb/check-rules.md` from them. Whole-repo rules (import cycles, inheritance depth) come in Phase 3 with the repo corpus to test them on.
402
+ - `grade/` with `report.py`. Rubric weights from frontmatter; the scoring formula written in `rubric.md`.
403
+ - `evals/fixtures/`: five bad samples with expected findings; one clean sample per rule with zero findings. API fixtures come in pairs, one Django and one FastAPI, with the same expected findings.
404
+ - Calibrate on `monopoly` and `requests-pro`, cloned by hand into gitignored `sources/repos/` (no `gh_fetch.py` yet); the repo and commit SHA used go in `evals/calibration/his.json`, which Phase 3's `gh_fetch.py` reads and extends.
405
+ - **Exit criterion (CI):** every fixture matches its expected findings exactly; two runs of `grade` on the same commit give identical JSON. **(manual):** the Nota mecânica meets the calibration rule in section 3 for `monopoly` and `requests-pro`, and every finding on them survives a hand review as true. **(release):** `0.1.0` is on PyPI.
406
+
407
+ ### Phase 3: Repo mining (3 sessions)
408
+ - `gh_fetch.py`: list repos for `henriquebastos` (61 public) and `HBNetwork` (11 public), shallow clone the mining list, write `sources/repos/manifest.json` with SHA, pushed date, license and class (`his` | `alumni`). Needs `gh auth` or `GITHUB_TOKEN` (unauthenticated REST is 60 requests an hour; search is capped at 1000 results and 10 requests a minute, 30 with auth).
409
+ - Pass 1, his code: the mining table in section 2, oldest to newest so drift shows up. The remaining repos are ingested one per later session in the order `gh_fetch.py` lists them.
410
+ - Pass 2, alumni: `gh_fetch.py --alumni` collects the 9 forks of `eventex`, a sample of 25 of the 224 forks of `pacote-desafios-pythonicos`, `pds-*` forks and the two API reimplementations. The eventex-style search is deferred until the rubric is stable. Clone shallow, run `check` and `grade` over all of them, keep the score distribution in `evals/calibration/alumni.json` keyed by opaque id (see "Public repo"). Read the five best and five worst by hand, locally; mistakes that recur become checker rules and synthetic eval fixtures.
411
+ - Mine `hamsterdan` first: its `engineering-conventions.md`, `AGENTS.md` and architecture tests are his rules in his words, and its `host/api.py` is the FastAPI reference. Then `monopoly`, `requests-pro`, `eventex`.
412
+ - `prompts/distill-repo.md`: what to extract (layout, test style, naming, error handling, packaging, Makefile, CI, README voice). Output `kb/repos/<name>.md` and new or amended `kb/patterns/`.
413
+ - Set `era` on tooling principles and patterns only; everything else stays `timeless`. Note drift between old and new repos as its own KB entry, so the report can say "he did this in 2013, not now".
414
+ - **Exit criterion (CI):** a test asserts every principle with `detectable: mechanical` or `partial` has at least one `his` example in `kb/patterns/`, cited with repo, path and commit, or with course, lesson and section for lesson code. **(manual):** `evals/calibration/alumni.json` exists and `eventex` and `pacote-desafios-pythonicos` each score at or above the median of their own forks on every timeless dimension of the Nota mecânica.
415
+
416
+ ### Phase 4: YouTube ingest (2-3 sessions)
417
+ - Channel id and playlists are pinned (see the inventory in section 2). `state/playlists.json` seeds from that table.
418
+ - `yt_fetch.py`: metadata plus `--write-auto-sub --sub-lang pt-orig --sub-format json3 --skip-download --sleep-subtitles 2`; convert json3 (`events[].tStartMs`, `segs[].utf8`; drop `aAppend` events and newline-only segs) to timestamped text, chunk per lesson and, inside a lesson, into windows of about 15 minutes with overlap. Auto captions have no punctuation and mis-hear names and code; the distiller must be told so.
419
+ - `prompts/distill-transcript.md`: the two PDFs' table of contents becomes the output schema of the distiller, so every course digest has the same shape: visão geral, filosofia e método, pilares conceituais, tabela de aulas, resumo por aula, princípios transversais, citações-chave, evolução técnica aula a aula, arsenal técnico, glossário, perguntas e respostas, repositórios, análise linha a linha do código real, execução real dos testes.
420
+ - The distiller works lesson by lesson from the timestamped transcript, then a second pass writes the cross-cutting sections. Timestamps survive into quotes and principle citations. A quote lifted from an auto caption carries `verified: false` and is rendered as a paraphrase with timestamp, not in quotation marks, until someone has listened to the clip and fixed the wording; only then is it a verbatim Portuguese quote.
421
+ - Ingest Raio-X da OO (0.7 h) as the pipeline smoke test, then Refatoração na Prática (4 h). The rest of tier 1 is ingested one playlist per later session, in table order.
422
+ - **Exit criterion (CI):** a third course digest exists under `kb/courses/` and a test checks it has every section of the digest schema. **(manual):** `evals/ask.md` gains two questions answerable only from the new course, each with an expected principle id and a lesson plus timestamp citation, and the installed skill answers both with the expected id and a citation that exists in the digest.
423
+
424
+ ### Phase 5: transform (2 sessions)
425
+ - `transform-playbook.md` with the ordered method and the stop rules.
426
+ - `evals/transform/magic-status/`: a Django view module (Django is a dev dependency) with magic status numbers, a bare `except` and a boolean error return, plus `tests/` that pass on it and `expected.md` listing which rule ids must be gone after the transform, which findings must remain (the boolean return: raising instead changes public behavior), and the public names and signatures that must survive. Django only in Phase 5; a FastAPI twin is Phase 7 work.
427
+ - Run on that fixture and on one small real module. Verify tests still pass, diff explained.
428
+ - **Exit criterion (manual run, CI verified):** the agent transforms the fixture; a CI test then runs the fixture's `tests/` on the committed `after/`, runs `check` on it and asserts the rule ids in `expected.md` are gone and the ones listed as remaining are still reported, and imports `after/` to assert the public names and signatures are unchanged.
429
+
430
+ ### Phase 6: watch (1 session)
431
+ - `watch.py`: list YouTube uploads from two keyless RSS feeds, the per-playlist feeds (`youtube.com/feeds/videos.xml?playlist_id=`, newest 15 each) and the channel feed (`youtube.com/feeds/videos.xml?channel_id=UCEbLV4AfUhoxNb_-Ionw83g`, newest 15 channel-wide, enough for a weekly run), plus the GitHub repo list with `pushed_at` from `gh api`; compare against `~/.henriquefy/state/*.json` (seeded from the shipped `state/playlists.json` on first run); print a queue of new sources with the ingest command to run. A video on the channel feed but in no known playlist is queued as "unassigned, check for a new playlist", since playlists cannot be listed without yt-dlp or an API key.
432
+ - Run weekly from cron or launchd on the maintainer's machine, or from any agent scheduler; the command is what matters. Results land in `~/.henriquefy/state/queue.md`.
433
+ - **Exit criterion (CI):** fixture feeds with one "new video" in a known playlist and one in none, against a temporary state file and no network, produce a queued ingest task and an unassigned entry.
434
+
435
+ ### Phase 7: Hardening (ongoing)
436
+ Two kinds of evals, and every exit criterion above is labeled with one. CI, no Claude: fixture
437
+ findings, Nota mecânica determinism, the install smoke test, citation ids resolving, digest schema
438
+ checks, generated files up to date, the transform fixture's after-state. Manual, agent in the
439
+ loop: `ask` against `evals/ask.md`, judgment findings, running `transform`, Nota do Henrique spread.
440
+ - Expand evals: Nota do Henrique spread over five runs on the same commit (report the range, no threshold yet); false-positive budget for mechanical rules: on his repos, a rule whose hand-reviewed false-positive rate is above 10% is demoted to `detectable: partial` and leaves the Nota mecânica.
441
+ - The FastAPI twin of the Phase 5 transform fixture. README with a worked example of each mode.
442
+
443
+ ## 5. Decisions and open questions
444
+
445
+ Assumed, change if wrong:
446
+ - KB language: course digests under `kb/courses/` stay in the language of the source, Portuguese, including the digest schema's section names and the principle `title` lines that quote his phrasing; principles, patterns, rubric, repo digests, career notes and reports are English; quotes are Portuguese verbatim, or a `verified: false` paraphrase when lifted from an auto caption.
447
+ - Public repo, MIT code, PyPI package `henriquefy`, installed with `uvx henriquefy install`. Henrique has approved publishing. Raw transcripts and clones stay out of git; distilled digests are committed.
448
+ - Code sources: all of his repos count, course-related or not. Alumni code is mined too, flagged `alumni`, used for calibration and mistake rules, never cited as his practice.
449
+ - Frameworks: principles are framework-free; patterns carry one rendition per framework, flagged `his` or `translated`. Django and FastAPI are both first-class from Phase 1; the checker detects the framework.
450
+ - Grading: strict 2026 by default, `--era` flag for calibration on old repos, era tags only on tooling principles.
451
+ - Ingest order after the two we have: tier 1 of the playlist inventory, Raio-X da OO first as a smoke test.
452
+
453
+ Decided 2026-10-08 after the adversarial review:
454
+ - Licenses: MIT for code, CC BY 4.0 for `kb/` except `kb/courses/`, which stays unlicensed (published with permission) until Henrique confirms in writing. Ivan will ask him to add MIT to `monopoly`, `eventex` and `pacote-desafios-pythonicos`.
455
+ - Nota do Henrique: judgment contribution unbounded but labeled until Phase 7 spread data exists; the letter grade attaches to it only.
456
+ - Python floor 3.12. Caption fetching stays, with the YouTube terms note in `NOTICE.md`.
457
+ - Phase 5 transform fixture is Django only; the FastAPI twin is Phase 7.
458
+ - Career playlists ingested in the career 1 to 4 order of the inventory.
459
+
460
+ Decided 2026-10-08 after the second review:
461
+ - The digests' HTML sources exist (added to the repo folder); Phase 1 converts HTML, not PDF.
462
+ - Digest quotes were not checked against video: all carry `verified: false`; the method goes in `NOTICE.md`.
463
+ - Phase 3 alumni pass samples 25 forks and hand-reads the five best and five worst.
464
+ - `grade` prints to stdout; `--report` writes `.henriquefy/report.md`.
465
+
466
+ No open questions.
467
+
468
+ ## 6. First concrete session
469
+
470
+ 1. Phase 0 scaffold: package, CLI `install`, CI, first commit, GitHub repo, pending publishers, `v0.0.1` release.
471
+ 2. `ingest/html_to_md.py`, run on both HTML digests.
472
+ 3. Write two OO principle files from section 12 of the OO digest, with citations, as the vertical slice; the other eight are Phase 1 work.
473
+ 4. Write `kb/INDEX.md` by hand for now; `build_index.py` comes in Phase 1.
474
+ 5. Minimal `skills/henriquefy/SKILL.md` with `ask` only, pointing at `references/kb/INDEX.md`. Install it with the CLI and try it on a snippet.
475
+ If the TestPyPI publish is not green by the end of the session, items 3 to 5 slip; the pipeline is the point of session one.
@@ -0,0 +1,17 @@
1
+ # henriquefy
2
+
3
+ Claude Code skills that know how [Henrique Bastos](https://github.com/henriquebastos) (HB Network)
4
+ writes Python, designs APIs, models objects and tests, and that apply it to your code.
5
+
6
+ ```
7
+ uvx henriquefy install # writes the henriquefy skill into ~/.claude/skills/
8
+ ```
9
+
10
+ Then, in Claude Code: `/henriquefy`, or just ask "what would Henrique do here?".
11
+
12
+ Status: Phase 0. The `ask` mode is live with a two-principle knowledge base; `check`, `grade` and
13
+ `transform` follow. The full plan is in [PLAN.md](PLAN.md).
14
+
15
+ Independent project, not affiliated with or endorsed by Henrique Bastos or HB Network; published
16
+ with his permission. See [NOTICE.md](NOTICE.md). Code is MIT; knowledge-base prose is CC BY 4.0
17
+ except the course digests.
@@ -0,0 +1,14 @@
1
+ # henriquefy knowledge base index
2
+
3
+ One line per principle: `id | category | detectable | rule`. Open `principles/<id>.md` for the
4
+ full entry with reasoning, examples and citations. Course digests are under `courses/`.
5
+
6
+ ## Principles
7
+
8
+ - deixe-o-codigo-descansar | simplicity | judgment | Let working code sit before refactoring; extract only the entity a concrete pain points at.
9
+ - prefira-excecoes-a-booleanos | errors | partial | Name each distinct outcome as a specific exception instead of returning a boolean and branching.
10
+
11
+ ## Courses
12
+
13
+ - oo-na-pratica | Orientação a Objetos na Prática, 23 lessons; principles 1 to 10 in section 12.
14
+ - design-api-na-pratica | Design de API na Prática, 9 lessons; four pillars, Richardson levels 0 to 3.