Knowunity · France · content machine
Obsonatus is a machine that automates high quality content production, distribution and planning.
| account | units | questions verified | posts | copy | decks rendered | scenes | videos | staged | approved |
|---|---|---|---|---|---|---|---|---|---|
| maths | 0 | 0/0 | 0 - | 0/0 | 0/0 | 0/0 | 0/0 | 0 | 0 |
| francais | 0 | 0/0 | 0 - | 0/0 | 0/0 | 0/0 | 0/0 | 0 | 0 |
| physique | 0 | 0/0 | 0 - | 0/0 | 0/0 | 0/0 | 0/0 | 0 | 0 |
| svt | 0 | 0/0 | 0 - | 0/0 | 0/0 | 0/0 | 0/0 | 0 | 0 |
| histgeo | 0 | 0/0 | 0 - | 0/0 | 0/0 | 0/0 | 0/0 | 0 | 0 |
| account | units | questions verified | posts | copy | decks rendered | scenes | videos | staged | approved |
|---|---|---|---|---|---|---|---|---|---|
| maths | 0 | 0/0 | 0 - | 0/0 | 0/0 | 0/0 | 0/0 | 0 | 0 |
| key | title | tier | handle | branded | hue | eyebrow | display name | bio | active |
|---|---|---|---|---|---|---|---|---|---|
| maths | Maths Première | 1 | not created | yes | neutral | MATHS 1RE | inactive | ||
| francais | Français Première | 1 | not created | no | magenta | FRANÇAIS 1RE | inactive | ||
| physique | Physique-Chimie Première | 1 | not created | yes | blue | PHYSIQUE-CHIMIE 1RE | inactive | ||
| svt | SVT Première | 1 | not created | yes | green | SVT 1RE | inactive | ||
| histgeo | Histoire-Géo Première | 1 | not created | no | brand | HISTOIRE-GÉO 1RE | inactive |
| source | files | status |
|---|---|---|
| curricula | 8 | present |
| unit and topic trees | 5 | present |
| textbook sequences | 0 | missing |
| standards, exam calendar, released questions | 2 | present |
| Knowunity app data (demand report, in-app search terms) | 0 | missing |
| TokPortal analytics | 0 | missing |
| account registry | 5 | present |
All files in this folder were fetched on 2026-09-22 with curl from the URLs below. PDFs are saved as delivered; the two programmes that only exist inside the 967-page Bulletin officiel spécial n°1 (20 MB, not saved) are saved as .md text extracted with pypdf, page markers kept. Nothing here is written from memory.
Reading rule: France has one national programme per subject and level, published in the Bulletin officiel (BO) by arrêté; the programme is the spine, exactly as the CED is for the US. There are no Länder. The programmes of 2019 are the ones in force for the rentrée 2026 (the ministry's own programme pages still link them; the 2026 BO changes touch the maths integrated into enseignement scientifique, not the spécialité). Teachers choose the order inside a programme ("La présentation du programme n'impose pas l'ordre de sa mise en œuvre", physique-chimie p. 2; SVT p. 3; français p. 55; histoire-géographie fixes the order of the thèmes but not the alternation of histoire and géographie), so the calendar order is an assumption recorded in the note of each unit's start week.
| Subject | Document title | URL | Fetched | Saved as |
|---|---|---|---|---|
| maths | Programme d'enseignement de spécialité de mathématiques de la classe de première de la voie générale (arrêté du 17 janvier 2019, BO spécial n°1 du 22 janvier 2019) | https://www.education.gouv.fr/sites/default/files/document/Programme%20de%20math%C3%A9matiques%20de%20premi%C3%A8re%20g%C3%A9n%C3%A9rale-248133.pdf | 2026-09-22 | maths_premiere_specialite.pdf (16 pages) and .md |
| physique | Programme d'enseignement de spécialité de physique-chimie de la classe de première de la voie générale (arrêté du 17 janvier 2019) | https://www.education.gouv.fr/sites/default/files/document/Programme%20de%20physique-chimie%20de%20premi%C3%A8re%20g%C3%A9n%C3%A9rale-251859.pdf | 2026-09-22 | physique_chimie_premiere_specialite.pdf (17 pages) and .md |
| svt | Programme d'enseignement de spécialité de sciences de la vie et de la Terre de la classe de première de la voie générale (arrêté du 17 janvier 2019) | https://cache.media.education.gouv.fr/file/CSP/81/2/1e_SVT_Specialite_Voie_generale_1023812.pdf | 2026-09-22 | svt_premiere_specialite.pdf (24 pages) and .md |
| francais | Programme de l'enseignement de français de la classe de seconde générale et technologique et de la classe de première des voies générale et technologique (arrêté du 17 janvier 2019, NOR MENE1901575A) | BO spécial n°1 du 22 janvier 2019, pages 34-61: https://www.education.gouv.fr/sites/default/files/document/SP1_MEN_22_1_2019_10H40_1064060.pdf-232533.pdf | 2026-09-22 | francais_seconde_premiere_bo2019.md (annexe 1 seconde p. 35-47, annexe 2 première p. 48-61) |
| histgeo | Programme de l'enseignement d'histoire-géographie de la classe de seconde générale et technologique, de la classe de première de la voie générale et de la classe de première de la voie technologique (arrêté du 17 janvier 2019, NOR MENE1901577A) | same BO, pages 62-94 | 2026-09-22 | histoire_geographie_seconde_premiere_bo2019.md (annexe 1 seconde p. 63-78, annexe 2 première générale p. 79-94; annexe 3 première technologique not saved) |
| francais | Programme national d'œuvres pour l'enseignement de français, année scolaire 2026-2027 (note de service du 4 juillet 2025, BO n°30 du 24 juillet 2025, NOR MENE2518792N) | https://www.education.gouv.fr/bo/2025/Hebdo30/MENE2518792N | 2026-09-22 | the BO page answers 403 to curl and to the fetch tool; the list was read from a third-party transcription and is recorded in ../standards/oeuvres_francais_2026_2027.md with that caveat |
eduscol.education.fr (301 to eduscol.education.gouv.fr), education.gouv.fr/bo/... and legifrance.gouv.fr answer 403 to curl and to the fetch tool; the file URLs under education.gouv.fr/sites/default/files/document/ and cache.media.education.gouv.fr serve PDFs. The old BO cache paths (cache.media.education.gouv.fr/file/SP1-MEN-22-1-2019/...) answer 404.rules/drafting_rules.md, rule F4): SVT prints a Précisions : block after nearly every section with "hors programme", "n'est pas attendu(e)", "ne sont pas attendus"; maths prints "Approfondissements possibles" ("en aucun cas obligatoires", p. 5) and "n'est pas un attendu du programme"; physique-chimie prints "Notions et contenus / Capacités exigibles" tables and defers content to Terminale in prose; français and histoire-géographie carry no exclusion statements at all.input/ holds raw sources: curricula (the Bulletin officiel programmes), textbooks, demand, standards (calendrier scolaire, épreuves du bac), tokportal analytics for France; the US counterpart is ../us/input/.
Metabase sits behind Google sign-in, so the API key alone cannot run this from the pipeline. Run it in the browser, export the result as CSV into this folder as <date>-topics.csv, and Claude turns it into <date>-topics.md in the shape of ../../../us/input/demand/2026-09-07-topics.md.
First check the table is current:
sql SELECT MAX(created_on) AS latest, COUNT(*) AS rows FROM knowunity-data-prod.knowunity_backend_lite.ai_chat_frequent_key_terms k WHERE k.country_id IN ( SELECT DISTINCT country_id FROM knowunity-data-prod.knowunity_backend_lite.subject WHERE country_code = 'FR')
Then the topic terms per subject for the lycée (grade levels 10 to 12 cover Seconde to Terminale; 11 is Première):
sql WITH fr AS ( SELECT DISTINCT country_id FROM knowunity-data-prod.knowunity_backend_lite.subject WHERE country_code = 'FR' ) SELECT s.name AS subject, g.level AS grade, k.key_term, SUM(k.frequency) AS freq FROM knowunity-data-prod.knowunity_backend_lite.ai_chat_frequent_key_terms k JOIN knowunity-data-prod.knowunity_backend_lite.subject s ON k.subject_id = s.id JOIN knowunity-data-prod.knowunity_backend_lite.grade g ON k.grade_id = g.id WHERE k.country_id IN (SELECT country_id FROM fr) AND g.level BETWEEN 10 AND 12 GROUP BY 1, 2, 3 QUALIFY ROW_NUMBER() OVER (PARTITION BY subject ORDER BY freq DESC) <= 30 ORDER BY subject, freq DESC
And the in-app search signal (table name to confirm with the data team, as for Germany):
sql -- placeholder until the search-events table is named -- SELECT subject, search_term, COUNT(*) AS n FROM <search events> WHERE country = 'FR' AND grade BETWEEN 10 AND 12 GROUP BY 1, 2 ORDER BY n DESC
The grade mapping (Seconde = 10, Première = 11, Terminale = 12) is an assumption to confirm against the grade table for FR before the first run.
Source: arrêté du 22 octobre 2025 fixant le calendrier scolaire de l'année 2026-2027, https://www.legifrance.gouv.fr/jorf/id/JORFTEXT000052416058 (read 2026-09-22 through the fetch tool; the site answers 403 to curl, so the text is transcribed here, not saved as HTML). The ministry page https://www.education.gouv.fr/calendrier-scolaire answers 403 as well.
| Moment | Zone A | Zone B | Zone C |
|---|---|---|---|
| Prérentrée des enseignants | 31 août 2026 | 31 août 2026 | 31 août 2026 |
| Rentrée des élèves | 1er septembre 2026 | 1er septembre 2026 | 1er septembre 2026 |
| Vacances de la Toussaint | 17 oct - 2 nov 2026 | 17 oct - 2 nov 2026 | 17 oct - 2 nov 2026 |
| Vacances de Noël | 19 déc 2026 - 4 jan 2027 | 19 déc 2026 - 4 jan 2027 | 19 déc 2026 - 4 jan 2027 |
| Vacances d'hiver | 13 fév - 1er mars 2027 | 20 fév - 8 mars 2027 | 6 fév - 22 fév 2027 |
| Vacances de printemps | 10 avr - 26 avr 2027 | 17 avr - 3 mai 2027 | 3 avr - 19 avr 2027 |
| Pont de l'Ascension | classes vaquent le 7 mai 2027 | idem | idem |
| Vacances d'été | 3 juillet 2027 | 3 juillet 2027 | 3 juillet 2027 |
Zones: A = Besançon, Bordeaux, Clermont-Ferrand, Dijon, Grenoble, Limoges, Lyon, Poitiers; B = Aix-Marseille, Amiens, Lille, Nancy-Metz, Nantes, Nice, Normandie, Orléans-Tours, Reims, Rennes, Strasbourg; C = Créteil, Montpellier, Paris, Toulouse, Versailles.
Unlike Germany, the rentrée, the Toussaint and the Noël breaks are the same date in the whole country, so W01 is far less fuzzy than in ../../../de/. Only the February and April breaks split by zone, and both fall after W16 if W01 lands in September or October.
Exam dates of the session 2027 that matter for Première (from the same search, 2026-09-22, to be confirmed against the BO when the ministry publishes the arrêté): épreuve écrite anticipée de français on Tuesday 15 June 2027 morning; the oral runs late June to early July.
Official source: note de service du 4 juillet 2025, BO n°30 du 24 juillet 2025 (NOR MENE2518792N), https://www.education.gouv.fr/bo/2025/Hebdo30/MENE2518792N. The page answers 403 to curl and to the fetch tool (2026-09-22). The list below was read on 2026-09-22 from https://www.laboiteabac.fr/oeuvres-bac-francais-2027/ , which transcribes the BO; cross-checked against the search summary of https://www.digischool.fr/articles/lycee/oeuvres-programme-bac-francais-2027/ (same twelve works). CAVEAT: third-party transcription; confirm the parcours wording against the BO page in a browser before any caption quotes it.
Structure (from the programme, ../curricula/francais_seconde_premiere_bo2019.md, BO p. 56-57): four objets d'étude, a national list of twelve works renewed by half every year (here only "roman et récit" changes), the teacher picks ONE work per objet d'étude, so each student studies four works. A post about one work reaches roughly a third of the classes; posts anchored on the parcours or the method reach all of them.
| Objet d'étude | Œuvre | Parcours associé |
|---|---|---|
| La poésie du XIXe au XXIe siècle | Arthur Rimbaud, Cahier de Douai (les 22 poèmes) | Émancipations créatrices |
| La poésie du XIXe au XXIe siècle | Francis Ponge, La Rage de l'expression | Dans l'atelier du poète |
| La poésie du XIXe au XXIe siècle | Hélène Dorion, Mes forêts | La poésie, la nature, l'intime |
| La littérature d'idées du XVIe au XVIIIe siècle | Étienne de La Boétie, Discours de la servitude volontaire | Défendre et entretenir la liberté |
| La littérature d'idées du XVIe au XVIIIe siècle | Fontenelle, Entretiens sur la pluralité des mondes | Le goût de la science |
| La littérature d'idées du XVIe au XVIIIe siècle | Françoise de Graffigny, Lettres d'une Péruvienne | Un nouvel univers s'est offert à mes yeux |
| Le roman et le récit du Moyen Âge au XXIe siècle (renouvelé 2027) | Chrétien de Troyes, Le Chevalier de la charrette | Le roman et l'invention de l'amour |
| Le roman et le récit du Moyen Âge au XXIe siècle (renouvelé 2027) | Émile Zola, Pot-Bouille | Dévoiler les rouages de la société |
| Le roman et le récit du Moyen Âge au XXIe siècle (renouvelé 2027) | Simone Schwarz-Bart, Pluie et vent sur Télumée Miracle | Tisser les mémoires, habiter le monde |
| Le théâtre du XVIIe au XXIe siècle | Pierre Corneille, Le Menteur | Mensonge et comédie |
| Le théâtre du XVIIe au XXIe siècle | Alfred de Musset, On ne badine pas avec l'amour | Les jeux du cœur et de la parole |
| Le théâtre du XVIIe au XXIe siècle | Nathalie Sarraute, Pour un oui ou pour un non | Théâtre et dispute |
Épreuve anticipée de français, session 2027 (from the same search, to confirm against the ministry's calendrier des épreuves when published): écrit mardi 15 juin 2027 matin, oral late June.
Not fetched yet (2026-09-22). The five accounts are tier 1: the Bulletin officiel programme is a national syllabus, so the calendars trace to ../curricula/ and the textbook pass is a calibration of the order inside a programme, which the BO leaves to the teacher.
Candidates to fetch, three per subject, tables of contents with source URL and date, in the shape of ../../../de/input/textbooks/mathe.md:
../standards/oeuvres_francais_2026_2027.md.Until they are fetched, every order decision in calendar/ is recorded as an assumption in the note of the unit's start week, with the reason (hour counts in the BO, dependency between notions, position of the first devoir surveillé).
Ce sont les seuls hooks qui atterrissent sur un deck français. Julian valide, corrige et complète cette liste ; ce qui n'y figure pas n'est pas posté. check_posts.py vérifie chaque deck contre ce fichier. La structure est celle de countries/us/rules/HOOKS.md et de countries/de/rules/HOOKS.md.
Principe de base, comme aux États-Unis : le hook PARLE au spectateur. Il le défie, lui promet quelque chose ou le prévient. Un hook qui se contente de décrire le sujet est interdit. Tutoiement partout, pas d'emojis, pas d'anglicismes inutiles, orthographe soignée (accents, cédilles, espace avant « ? » et « : »).
« MATHS 1RE », « SVT : LES BASES », « FRANÇAIS ÉDITION BAC » sont des EYEBROWS : petites étiquettes de série ou de matière au-dessus ou au-dessous du hook. Elles ne sont jamais le hook lui-même. L'eyebrow est dans la registry (accounts.json) ; le post spec peut le remplacer post par post.
Modèles :
Modèles :
Modèles :
L'indication de temps doit être vraie : « 30 jours avant ton DS » seulement si le batch sort environ un mois avant une phase de DS ou de bac blanc (rules/calendar_moments.md : W07-W09 et W15-W16).
Modèles :
Modèles :
Encore vide. Julian donne la formulation, puis elle remplace ou complète les modèles ci-dessus, comme dans la section « Von Julian gesetzt » du fichier allemand.
Jamais deux fois de suite le même modèle sur un compte. Les trois posts practice d'une semaine utilisent des modèles différents des familles 1 et 2. Aucun modèle plus d'environ trois fois par batch. check_posts.py l'impose ; chaque post planifié note son modèle pour que la performance se lise par modèle.
> Proposition de Claude (2026-09-22), en attente de la formulation de Julian. Les deux lignes > standard ci-dessous traduisent la paire US de Julian ; tout le reste est une proposition.
Comme HOOKS.md : les seuls CTA qui atterrissent sur un deck français (les vidéos collage utilisent CTAS_COLLAGE.md). Le CTA parle au spectateur, une phrase, jamais deux empilées. Chaque deck a exactement une slide CTA. Julian valide le CTA avec le hook.
| # | Famille | Modèles | Pour |
|---|---|---|---|
| 1 | S'abonner | « Tu as aimé ce post ? Abonne-toi pour la suite », « Abonne-toi pour la suite », « Tu en veux plus ? Alors abonne-toi », « Abonne-toi pour demain : [prochain thème] », « Tu veux la partie 2 ? Abonne-toi » | par défaut, tout post |
| 2 | Appli | « Tu as aimé ce post ? On a une appli pour toi », « Tu as aimé ce quiz ? Il y en a 1000 autres sur Knowunity », « On a plus pour toi sur Knowunity », « Tu en veux plus ? Tout est sur Knowunity », « Le chapitre complet est sur Knowunity » | concept, practice |
| 3 | Enregistrer | « Enregistre ça pour ton prochain DS », « Fais une capture avant d'en avoir besoin », « Enregistre, tu en auras besoin dans [N] semaines », « Enregistre avant le bac blanc » | concept, fiches |
| 4 | Répondre | « Écris ta réponse en commentaire, la correction arrive dans le prochain post », « Tu en as eu combien ? Sois honnête », « Laquelle tu as choisie ? Dis-le en commentaire » | practice |
| 5 | Milieu de deck | « Ça va jusque-là ? Abonne-toi pour la suite », « On est à la moitié. Abonne-toi avant d'oublier », « Si tu es arrivé jusqu'ici, abonne-toi pour le reste » | CTA en slide 4 seulement |
Encore vide. Julian donne la formulation, puis elle remplace ce tableau.
Jamais deux fois de suite le même modèle sur un compte. Sur un batch, les familles 1 et 2 se partagent à peu près à parts égales ; 3 et 4 sont la variété. check_posts.py l'impose.
Le script parlé d'une vidéo collage. Fichier frère de HOOKS.md (le hook sur l'image), CTAS_COLLAGE.md et CAPTIONS.md. Chaque règle note l'erreur qui l'a créée. draft.py <batch> scenes lit ce fichier. La structure est celle de countries/us/rules/SCRIPTS.md ; les formulations sont françaises, tutoiement, pas d'emojis.
Une vidéo dure 40 secondes, environ 88 mots parlés, huit scènes après 00_empty.
| Scène | Mots | Rôle |
|---|---|---|
| Hook | 12-14 | question directe au spectateur, puis la ligne de série |
| Setup | 12-15 | ce que la chose EST, avant d'expliquer quoi que ce soit dessus |
| Beat 1a | 10-12 | premier sous-concept : l'énoncé |
| Beat 1b | 10-12 | le même sous-concept : pourquoi ça compte |
| Beat 2a | 10-12 | deuxième sous-concept : l'énoncé |
| Beat 2b | 10-12 | le même sous-concept : pourquoi ça compte |
| Récap | 9-11 | l'image que l'on capture |
| CTA | 6-13 | la partie deux ou l'appli |
Deux sous-concepts bien expliqués, jamais quatre effleurés.
Une phrase par scène. 40 secondes, ce sont huit coupes, pas six plans fixes plus longs : environ onze mots par scène, soit cinq secondes, exactement la durée d'un clip Seedance. Si la narration d'une scène dépasse son clip, assemble.py fige la dernière image. Un sous-concept qui demande deux phrases reçoit deux scènes avec deux images.
Une phrase complète ou une question complète adressée à une personne, et le sujet est DANS cette phrase. Modèles, tirés de HOOKS.md et des hooks de Julian :
Ensuite, optionnel, la transition et la ligne de série : « C'est parti : Maths, les bases. »
PROVISOIRE : « 101 » est américain. La ligne de série française est ici « [Matière], les bases », parce que c'est la formulation de hook de Julian transposée. Julian confirme ou remplace avant le premier script français.
Un simple groupe nominal de deux ou trois mots derrière la ligne de série est interdit. « Maths, les bases, probabilités conditionnelles » est aussi faux que l'anglais « Chem 101, limiting reactants ». Si le sujet doit être nommé, c'est dans une phrase du hook.
Julian, 2026-09-18 : « put this as a hard no, I dont want to see any of those bullshit 2 3 words there that mean nothing and are just confusing. »
La scène après le hook dit ce qu'est le sujet. Une phrase comme « la plupart se trompent ici » ne peut pas venir en premier, parce que rien n'a encore été dit sur ce en quoi consiste l'erreur.
L'erreur : le script de chimie commençait par « la plupart prennent juste la plus petite masse, c'est le piège », alors que la vidéo n'avait encore dit que « AP Chem ».
Aucune conjonction, aucun article, aucun auxiliaire n'est supprimé pour gagner un mot. Une coupe qui casse la grammaire n'est pas une coupe, c'est une erreur que la voix lit à haute voix.
L'erreur (anglais) : « Congress could ask the states for money, never demand it. » Le « but » manquait. En français : « pouvait demander, mais pas exiger », jamais « pouvait demander, jamais exiger ».
Si le concept a des étapes, des phases ou des stades, la vidéo commence à la première ou ne numérote pas.
L'erreur : le script de géographie commençait par « en phase deux » et ne mentionnait jamais la phase un. Julian : « you just left out stage 1? »
Si un concept a plus de deux sous-concepts (quatre phases, trois types d'erreurs, trois raisons), deux au plus sont expliqués correctement, et le spectateur est renvoyé à la suite. La scène finale porte alors la ligne partie-deux au lieu de la ligne appli :
> « Tu veux la partie 2 ? Abonne-toi. »
Ce qui vient en partie deux est nommé (« les phases trois et quatre arrivent »), pour que la promesse soit concrète. PROVISOIRE : la formulation exacte de la ligne partie-deux dépend de CTAS_COLLAGE.md, que Julian valide.
CTAS_COLLAGE.md.Jamais les deux dans une vidéo.
La voix peut dire le terme qui figure sur le label si c'est exactement ce terme qui est expliqué. Elle ne peut jamais se contenter de lire le label sans rien ajouter.
video_briefs.md s'applique aussi ici)Chaque ligne commence par un tag d'émotion entre crochets. Pas de sous-titres incrustés. La substance est aussi sur l'image : si le son coupe, le label et les découpes expliquent encore le beat.
Un concept coupé selon la règle 6 doit une partie deux, et cette promesse est une donnée, pas une ligne parlée. Le post spec porte sur les deux posts un objet series :
json "series": {"key": "dtm", "part": 1, "of": 2, "owes": "les phases trois et quatre"} "series": {"key": "dtm", "part": 2, "of": 2, "covers": "les phases trois et quatre"}
plan_parts.py <batch> transforme le prochain slot collage libre de la semaine en partie deux, avec la même unité, le même angle plus « (part 2) » et un hook vide pour le drafting. S'il n'y a pas de slot libre, il le dit : la promesse n'est alors pas tenable. check_posts.py signale une partie un sans partie deux, un CTA qui ne porte pas la ligne partie-deux, ou une partie deux sur une autre unité.
Comment sonnent les deux vidéos :
COUNTRY=fr python projects/content/check_scenes.py <batch> vérifie chaque script sur le disque contre ce fichier et tourne dans run_batch.sh juste après check_posts.py. Les vérifications sont dans lib/scene_rules.py et tournent au drafting comme en CLI, un script écrit à la main est donc contrôlé de la même façon.
Machine : règle 1 (adresse à la deuxième personne), règle 2 (pas de fragment derrière la ligne de série), règle 5 (pas de suite au-dessus de son premier élément), règles 6 et 7 (la ligne finale est la ligne partie-deux ou la ligne appli), le nombre de scènes, le budget de mots et la mécanique (tag d'émotion, placeholders, pas de hex, la mascotte jamais dans le prompt Seedance).
Humain seulement : si le setup construit vraiment (règle 3), le français complet (règle 4), si les deux sous-concepts choisis sont les bons (règle 6), si une ligne complète son label ou ne fait que le répéter (règle 8).
> French version drafted 2026-09-22 from the US shape (../../us/rules/CAPTIONS.md); pools and label > format are proposals until Julian rules.
Goal: rank in TikTok SEARCH for niche keywords competitors are not targeting. Keyword-rich explanatory descriptions beat "cool" copy.
TokPortal has ONE text field per post. Caption, description and hashtags are all the same string, sent as caption in the staging manifest. There is no separate hashtag field.
1. LABEL LINE - the searchable name of exactly what this post teaches, on its own line, because TikTok shows only ~100 characters before the "more" cut. Format: <Matière> Première <code court> : <nom du thème>, e.g. "Maths Première 1.2 : Équations et fonctions polynômes du second degré", "SVT Première 1.1.2 : La réplication de l'ADN", "Histoire Première H1.1 : La Révolution française et l'Empire", "Français Première P.1 : Rimbaud, Cahier de Douai". The matière, code and name are read from the backing calendar row and knowledge/<subject>/structure.json (the code without its M-1RE- / PC-1RE- / SVT-1RE- / HG-1RE- / FR-1RE- prefix), never typed from memory. French spacing before the colon. 2. BODY - 400-700 characters, roughly 3-5 sentences, written from the approved content unit: what it is, the mechanism in one pass, and the named misconception. Plain language, the words a student would type into search, spelled out at least once ("physique-chimie", not only "PC"; "devoir surveillé" once, then "DS"). Tutoiement. 3. CTA - one sentence, strong, from CTAS.md: "enregistre ça pour ton prochain DS", "écris ta réponse en commentaire, la correction arrive dans le prochain post", "abonne-toi pour demain : <prochain thème>". 4. HASHTAGS - exactly 4, on the last line (see below).
No "Partie N" series counter. The label line does the sequencing honestly. No emojis unless the batch file says "emojis": true, and then at most 1-2, chosen deliberately. No ministry disclaimer.
Exactly 4 per post, 2 + 2:
All lowercase, ASCII only (no accents in hashtags: #seconddegre, #genetique, #revolutionfrancaise), French spelling otherwise. If a topic tag collides with a pool pick, re-draw the pool pick.
maths: #maths #spemaths #premiere #lycee #bac #revisions #mathsfacile #coursdemaths francais: #francais #bacdefrancais #premiere #lycee #bac2027 #revisions #litterature #commentaire physique: #physiquechimie #spephysique #premiere #lycee #bac #revisions #chimie #physique svt: #svt #spesvt #premiere #lycee #bac #revisions #biologie #geologie histgeo: #histoire #geographie #histoiregeo #premiere #lycee #bac #revisions #coursdhistoire
Pools are v1, built from subject and exam vocabulary; #bac2027 is right for the Première cohort's épreuve anticipée de français, the other accounts use the timeless #bac. Validate and refine with the TikTok Keyword Planner once API access exists.
Captions are DRAFTED into captions/<batch>.json from the approved content unit, alongside the hook, CTA and style, applied to the post specs by apply_captions.py <batch>, and reviewed with them. Julian approves by exception: he sees the week's caption sheet and flags what is off.
Nothing renders or sends on an unverified unit, so a caption can never assert something the unit has not been blind-verified on.
Maths Première 1.2 : Équations et fonctions polynômes du second degré
La forme canonique, c'est le trinôme réécrit en a(x - alpha)² + beta : alpha et beta sont les coordonnées du sommet de la parabole, et le signe de a dit si elle est tournée vers le haut ou vers le bas. On l'obtient en complétant le carré avec x² + 2ax = (x + a)² - a², la seule identité à connaître. L'erreur classique au devoir surveillé : oublier de sortir le facteur a avant de compléter le carré, ce qui décale le sommet. Spé maths Première, chapitre second degré.
Enregistre ça pour ton prochain DS.
Carousels always get a TikTok sound (sound_url in the post spec); videos with VO never do. Pool in SOUNDS.md, still the US pool.
> French pool = the US pool for now (same ruling as Germany, 2026-09-11); replace links here when French sounds exist.
Every carousel carries a TikTok sound; collage videos never do (they have narration). scaffold_posts.py fills sound_url on every carousel post from the table below, rotating in order per account so no two consecutive posts of an account share a sound. Julian overrides any post's sound_url in the post spec before review, and adds or retires sounds here. The URL column is the only thing the code reads.
| URL | First used | Posts |
|---|---|---|
| https://vt.tiktok.com/ZS9BWE7q79aWU-KC7H1/ | 2026-08-18 | 39 |
| https://vt.tiktok.com/ZS9k4FrPfvjDa-S6L8w/ | 2026-08-31 | 13 |
| https://vt.tiktok.com/ZS9k4F8hdkS3C-sARkR/ | 2026-08-31 | 13 |
| https://vt.tiktok.com/ZS9k4F6nM11XD-VRDM3/ | 2026-08-31 | 13 |
| https://vt.tiktok.com/ZS9k4FFR9vVhN-QuGa2/ | 2026-08-31 | 10 |
| https://vt.tiktok.com/ZS9BWEpRS5V2u-PqCcr/ | 2026-08-18 | 6 |
| https://vt.tiktok.com/ZS9BWEnCvd3os-bigD1/ | 2026-08-18 | 6 |
| https://vt.tiktok.com/ZS9BWoeB4GmMn-XZeiX/ | 2026-08-19 | 5 |
| https://vt.tiktok.com/ZS9BWE7vR4bTg-Zusvt/ | 2026-08-18 | 5 |
| https://vt.tiktok.com/ZS9BWodfwxyrn-B25Lt/ | 2026-08-19 | 4 |
| https://vt.tiktok.com/ZS9BWoNVjDR2F-NZSJP/ | 2026-08-19 | 4 |
| https://vt.tiktok.com/ZS9BWoN5fMyqN-cmZqp/ | 2026-08-19 | 4 |
"Posts" counts the scheduled US carousels in the staging manifests up to B01 (2026-09-08).
The fixture batch BFIX is not rendered; run render.py BFIX.