bookwright-cli 0.2.0__py3-none-any.whl

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 (149) hide show
  1. bookwright/__init__.py +3 -0
  2. bookwright/__main__.py +6 -0
  3. bookwright/cli.py +19 -0
  4. bookwright/commands/__init__.py +0 -0
  5. bookwright/commands/_envelope.py +36 -0
  6. bookwright/commands/check.py +75 -0
  7. bookwright/commands/graph/__init__.py +23 -0
  8. bookwright/commands/graph/build.py +157 -0
  9. bookwright/commands/graph/envelope.py +26 -0
  10. bookwright/commands/graph/query.py +98 -0
  11. bookwright/commands/init/__init__.py +5 -0
  12. bookwright/commands/init/conflict.py +107 -0
  13. bookwright/commands/init/envelope.py +322 -0
  14. bookwright/commands/init/git.py +96 -0
  15. bookwright/commands/init/main.py +263 -0
  16. bookwright/commands/init/resolve.py +193 -0
  17. bookwright/commands/init/scaffold.py +242 -0
  18. bookwright/commands/init/validate.py +172 -0
  19. bookwright/commands/integration/__init__.py +22 -0
  20. bookwright/commands/integration/use.py +120 -0
  21. bookwright/commands/validate.py +160 -0
  22. bookwright/commands/version.py +35 -0
  23. bookwright/core/__init__.py +35 -0
  24. bookwright/core/_blocks.py +239 -0
  25. bookwright/core/_build.py +154 -0
  26. bookwright/core/_research_block.py +56 -0
  27. bookwright/core/_translate.py +90 -0
  28. bookwright/core/errors.py +127 -0
  29. bookwright/core/iso639_1.py +200 -0
  30. bookwright/core/manifest.py +343 -0
  31. bookwright/errors.py +47 -0
  32. bookwright/golem/__init__.py +71 -0
  33. bookwright/golem/base.py +200 -0
  34. bookwright/golem/errors.py +29 -0
  35. bookwright/golem/modules/__init__.py +1 -0
  36. bookwright/golem/modules/character.py +109 -0
  37. bookwright/golem/modules/event.py +91 -0
  38. bookwright/golem/modules/feature.py +161 -0
  39. bookwright/golem/modules/inference.py +41 -0
  40. bookwright/golem/modules/narrative.py +55 -0
  41. bookwright/golem/modules/provenance.py +197 -0
  42. bookwright/golem/modules/relationship.py +38 -0
  43. bookwright/golem/modules/setting.py +30 -0
  44. bookwright/golem/namespaces.py +332 -0
  45. bookwright/golem/serialize.py +25 -0
  46. bookwright/golem/slug.py +22 -0
  47. bookwright/indexers/__init__.py +47 -0
  48. bookwright/indexers/base.py +55 -0
  49. bookwright/indexers/errors.py +80 -0
  50. bookwright/indexers/rdflib_indexer.py +89 -0
  51. bookwright/integrations/__init__.py +155 -0
  52. bookwright/integrations/base.py +117 -0
  53. bookwright/integrations/claude/__init__.py +29 -0
  54. bookwright/integrations/constants.py +38 -0
  55. bookwright/integrations/descriptions.py +48 -0
  56. bookwright/integrations/errors.py +170 -0
  57. bookwright/integrations/generic/__init__.py +56 -0
  58. bookwright/integrations/lint.py +160 -0
  59. bookwright/integrations/materialize.py +202 -0
  60. bookwright/integrations/options.py +203 -0
  61. bookwright/io/__init__.py +1 -0
  62. bookwright/io/bible.py +500 -0
  63. bookwright/io/errors.py +98 -0
  64. bookwright/io/frontmatter.py +61 -0
  65. bookwright/io/fs.py +226 -0
  66. bookwright/io/manuscript.py +15 -0
  67. bookwright/io/project.py +21 -0
  68. bookwright/io/report.py +107 -0
  69. bookwright/io/research.py +427 -0
  70. bookwright/resources/__init__.py +1 -0
  71. bookwright/resources/commands/bookwright-analyze.md +66 -0
  72. bookwright/resources/commands/bookwright-bible.md +96 -0
  73. bookwright/resources/commands/bookwright-checklist.md +67 -0
  74. bookwright/resources/commands/bookwright-clarify.md +65 -0
  75. bookwright/resources/commands/bookwright-constitution.md +79 -0
  76. bookwright/resources/commands/bookwright-continuity.md +70 -0
  77. bookwright/resources/commands/bookwright-draft.md +74 -0
  78. bookwright/resources/commands/bookwright-outline.md +71 -0
  79. bookwright/resources/commands/bookwright-research.md +107 -0
  80. bookwright/resources/commands/bookwright-scenes.md +66 -0
  81. bookwright/resources/commands/bookwright-synopsis.md +67 -0
  82. bookwright/resources/commands/bookwright-verify.md +136 -0
  83. bookwright/resources/commands/references/golem-character.md +65 -0
  84. bookwright/resources/commands/references/golem-events-timeline.md +56 -0
  85. bookwright/resources/commands/references/golem-relationships.md +53 -0
  86. bookwright/resources/commands/references/greimas-actants.md +57 -0
  87. bookwright/resources/commands/references/pending-protocol.md +72 -0
  88. bookwright/resources/commands/references/propp-functions.md +54 -0
  89. bookwright/resources/commands/references/research-format.md +136 -0
  90. bookwright/resources/project/.bookwright/cache/.gitkeep +0 -0
  91. bookwright/resources/project/.bookwright/schema/.gitkeep +0 -0
  92. bookwright/resources/project/.bookwright/templates/.gitkeep +0 -0
  93. bookwright/resources/project/.gitignore +23 -0
  94. bookwright/resources/project/README.md.j2 +40 -0
  95. bookwright/resources/project/__init__.py +6 -0
  96. bookwright/resources/project/bible/characters/.gitkeep +0 -0
  97. bookwright/resources/project/bible/constitution.md.j2 +74 -0
  98. bookwright/resources/project/bible/glossary.md +36 -0
  99. bookwright/resources/project/bible/locations/.gitkeep +0 -0
  100. bookwright/resources/project/bible/pov-structure.md +43 -0
  101. bookwright/resources/project/bible/relationships.md +36 -0
  102. bookwright/resources/project/bible/research/_index.md +28 -0
  103. bookwright/resources/project/bible/research/sources.md +23 -0
  104. bookwright/resources/project/bible/settings/.gitkeep +0 -0
  105. bookwright/resources/project/bible/subplots.md +35 -0
  106. bookwright/resources/project/bible/themes.md +36 -0
  107. bookwright/resources/project/bible/timeline.md +38 -0
  108. bookwright/resources/project/manuscript/.gitkeep +0 -0
  109. bookwright/resources/project/outline/arcs.md +34 -0
  110. bookwright/resources/project/outline/scenes.md +31 -0
  111. bookwright/resources/project/outline/structure.md +35 -0
  112. bookwright/resources/project/outline/synopsis.md +25 -0
  113. bookwright/resources/schemas/__init__.py +19 -0
  114. bookwright/resources/schemas/golem-1.1/VERSION +1 -0
  115. bookwright/resources/schemas/golem-1.1/golem.ttl +1947 -0
  116. bookwright/resources/schemas/golem-1.1/version.json +8 -0
  117. bookwright/resources/templates/__init__.py +1 -0
  118. bookwright/resources/templates/bible/character.md.tmpl +63 -0
  119. bookwright/resources/templates/bible/location.md.tmpl +37 -0
  120. bookwright/resources/templates/bible/research/_index.md.tmpl +25 -0
  121. bookwright/resources/templates/bible/research/sources.md.tmpl +21 -0
  122. bookwright/resources/templates/bible/research/tema.md.tmpl +37 -0
  123. bookwright/resources/templates/bible/setting.md.tmpl +38 -0
  124. bookwright/resources/templates/manifest.template.toml +79 -0
  125. bookwright/resources/templates/manuscript/chapter.md.tmpl +36 -0
  126. bookwright/resources/templates/scenes/scene.md.tmpl +37 -0
  127. bookwright/resources/vocabularies/__init__.py +6 -0
  128. bookwright/resources/vocabularies/greimas.ttl +4 -0
  129. bookwright/resources/vocabularies/propp.ttl +4 -0
  130. bookwright/resources/vocabularies/sources.ttl +82 -0
  131. bookwright/validation/__init__.py +33 -0
  132. bookwright/validation/anchor_queries.py +223 -0
  133. bookwright/validation/base.py +233 -0
  134. bookwright/validation/queries.py +197 -0
  135. bookwright/validation/registry.py +185 -0
  136. bookwright/validation/report.py +106 -0
  137. bookwright/validation/runner.py +65 -0
  138. bookwright/validation/validators/__init__.py +9 -0
  139. bookwright/validation/validators/character_presence.py +202 -0
  140. bookwright/validation/validators/factual_anchor.py +291 -0
  141. bookwright/validation/validators/focalization.py +152 -0
  142. bookwright/validation/validators/setting_continuity.py +100 -0
  143. bookwright/validation/validators/temporal.py +277 -0
  144. bookwright_cli-0.2.0.dist-info/METADATA +218 -0
  145. bookwright_cli-0.2.0.dist-info/RECORD +149 -0
  146. bookwright_cli-0.2.0.dist-info/WHEEL +4 -0
  147. bookwright_cli-0.2.0.dist-info/entry_points.txt +2 -0
  148. bookwright_cli-0.2.0.dist-info/licenses/LICENSE +202 -0
  149. bookwright_cli-0.2.0.dist-info/licenses/NOTICE +14 -0
@@ -0,0 +1,136 @@
1
+ ---
2
+ name: bookwright-verify
3
+ description: >-
4
+ Verifica el manuscrito ya redactado contra las anclas de investigación:
5
+ detecta pasajes que contradicen lo investigado — anacronismos, errores de
6
+ procedimiento (algo ilegal o imposible en la ambientación) e inexactitudes
7
+ culturales o lingüísticas. Verify the drafted manuscript against the research
8
+ anchors: flag passages that contradict the research — anachronisms, procedural
9
+ errors (something illegal or impossible in the setting) and cultural or
10
+ linguistic inaccuracies. Úsalo cuando el autor pida "verifica si mi manuscrito
11
+ contradice lo investigado" / "check my manuscript against my research". Es de
12
+ solo lectura y trabaja en fase POST-draft. NO compara el manuscrito con la
13
+ biblia (eso es bookwright-continuity) ni audita la integridad estructural de
14
+ las anclas (eso es el validator factual_anchor).
15
+ ---
16
+
17
+ # /bookwright-verify
18
+
19
+ ## Rol
20
+
21
+ Eres un verificador de fidelidad factual. Tu tarea es **comparar el manuscrito
22
+ ya redactado** con las **anclas de investigación** del proyecto y reportar los
23
+ pasajes que contradicen lo investigado, **sin tocar nada**. No eres editor de la
24
+ biblia (eso es `bookwright-continuity`) ni auditas la integridad estructural de
25
+ las anclas (eso es el validator `factual_anchor`): tú juzgas si la prosa
26
+ **respeta los hechos** que el autor investigó.
27
+
28
+ ## Input
29
+
30
+ `{ARGS}` — foco opcional (p. ej. un capítulo o un tema). La base es el
31
+ **manuscrito** (`manuscript/`) cotejado contra las **anclas** y las **fuentes**
32
+ que las respaldan, leídas del grafo del proyecto.
33
+
34
+ ## Procedimiento
35
+
36
+ 1. **Refresca y carga el grafo.** Ejecuta `bookwright graph build --json` para
37
+ reconstruir la caché derivada (`bible/graph.ttl`) y luego
38
+ `bookwright graph query "<SPARQL>"` para cargar las anclas y las fuentes que
39
+ las respaldan. Una **ancla** es un `crm:E13_Attribute_Assignment` que lleva un
40
+ `bw:promotes`; **no existe** una clase `bw:Anchor`/`bw:Source` que puedas
41
+ emparejar por `rdf:type` (una `Source` se tipa solo vía
42
+ `crm:P2_has_type → crm:E55_Type`). Recorre la cadena
43
+ **ancla `—bw:promotes→` hallazgo (`bw:claim`) `—bw:supportedBy→` fuente** para
44
+ leer el hecho investigado y su procedencia. Consulta de referencia:
45
+
46
+ ```sparql
47
+ PREFIX bw: <https://bookwright.dev/vocab/bw#>
48
+ PREFIX crm: <http://www.cidoc-crm.org/cidoc-crm/>
49
+ SELECT ?anchor ?claim ?target ?source ?reference ?author ?reliability ?originalQuote ?translation WHERE {
50
+ ?anchor bw:promotes ?finding .
51
+ OPTIONAL { ?anchor bw:constrains ?target . } # la entidad narrativa que restringe (puede faltar)
52
+ ?finding bw:claim ?claim . # el hecho investigado
53
+ OPTIONAL {
54
+ ?finding bw:supportedBy ?source . # procedencia detrás del ancla
55
+ OPTIONAL { ?source bw:reference ?reference . }
56
+ OPTIONAL { ?source bw:author ?author . }
57
+ OPTIONAL { ?source bw:reliability ?reliability . }
58
+ OPTIONAL { ?source bw:originalQuote ?originalQuote . }
59
+ OPTIONAL { ?source bw:translation ?translation . } # presente si la lengua de la fuente ≠ la del libro
60
+ }
61
+ }
62
+ ```
63
+
64
+ 2. **Lee el manuscrito** (`manuscript/`), acotado a `{ARGS}` si se indicó.
65
+ 3. **Caza las contradicciones.** Busca pasajes que **contradigan** un ancla en
66
+ los tres ejes de § 20.6:
67
+ - **anacronismos** (algo presente fuera de su época),
68
+ - **errores de procedimiento** (algo ilegal o imposible en la ambientación),
69
+ - **inexactitudes culturales o lingüísticas**.
70
+ Un pasaje puede romper varias anclas: regístralas todas.
71
+ 4. **Maneja los prerrequisitos ausentes** (→ "Información faltante"): sin
72
+ manuscrito, o sin anclas / con `[research].enabled = false`, repórtalo y no
73
+ inventes contradicciones.
74
+ 5. **Redacta el reporte** con la forma de la sección "Output". No edites ni
75
+ corrijas nada: el autor decide qué arreglar.
76
+
77
+ Reutiliza el vocabulario `bw:`/CIDOC existente; no añadas clases ni predicados.
78
+
79
+ ## Output
80
+
81
+ Un **reporte en prosa** legible por humanos (no un envoltorio JSON), **agrupado
82
+ por capítulo/escena**. Bajo cada escena, cero o más hallazgos. Cada hallazgo
83
+ lleva cuatro partes más su localización:
84
+
85
+ - **(a) pasaje citado** — la prosa infractora del manuscrito, entre comillas.
86
+ - **(b) ancla violada** — el hecho investigado (`bw:claim`) que el pasaje rompe;
87
+ si rompe N anclas, lístalas todas.
88
+ - **(c) fuente** — la procedencia detrás del ancla (alcanzada vía
89
+ `bw:supportedBy`): `bw:reference` / `bw:author` / `bw:reliability` /
90
+ `bw:originalQuote`, citada **tal como la registra el grafo** (incluidas las
91
+ referencias en lengua original).
92
+ - **(d) gravedad** — una de `error` / `warning` / `info` (`error > warning >
93
+ info`), el vocabulario `Severity` del sistema de validación.
94
+ - **localización** — `file:line` cuando se conoce; si no, el capítulo/escena
95
+ **sin inventar un número de línea**.
96
+
97
+ **Rúbrica de gravedad:** contradicción factual definida (anacronismo duro;
98
+ procedimiento ilegal o imposible) → `error`; matiz cultural o estilístico blando
99
+ → `warning`/`info`. Una contradicción discutible se registra con **menor
100
+ gravedad**, nunca suprimida ni exagerada. Un manuscrito limpio produce **cero
101
+ hallazgos**: no fabriques problemas para llenar el reporte.
102
+
103
+ ## Archivos a leer
104
+
105
+ - `manuscript/` (acotado por `{ARGS}` si se indicó).
106
+ - El **grafo** del proyecto: anclas y fuentes vía `bookwright graph query`
107
+ (cadena `bw:promotes` → `bw:supportedBy`).
108
+ - El bloque `[research]` de `manifest.toml` (para detectar `enabled = false`).
109
+
110
+ ## Archivos a escribir
111
+
112
+ - Ninguno. Este comando es de **solo lectura**: **no escribe nada** en el
113
+ proyecto; solo emite un reporte (incluido el grafo que `graph build`
114
+ reconstruye como caché derivada).
115
+
116
+ ## Información faltante
117
+
118
+ - **Sin manuscrito que verificar** → repórtalo como "prerrequisito ausente"
119
+ (nada que verificar) e indica que primero hay que redactar con
120
+ `bookwright-draft`. No falles de forma opaca.
121
+ - **Sin anclas** (no hay `bible/research/`, ninguna ancla promovida, o
122
+ `[research].enabled = false`) → repórtalo como "nada que verificar", con
123
+ **cero** contradicciones.
124
+ - No marques `[PENDING: …]`: este comando no escribe archivos.
125
+
126
+ ## Qué NO hacer
127
+
128
+ - No edites ni corrijas el manuscrito ni ningún otro archivo: solo reporta.
129
+ - No reaudites la **integridad estructural** de las anclas: eso es el validator
130
+ `factual_anchor`.
131
+ - No busques en internet, no descargues fuentes ni añadas dependencias: razona
132
+ con el grafo y el manuscrito que ya tienes.
133
+ - No inventes contradicciones para "llenar" el reporte: un manuscrito coherente
134
+ da cero hallazgos.
135
+ - No compares el manuscrito con la **biblia**: eso es `bookwright-continuity`.
136
+ - No omitas el `bookwright graph build --json` previo a la consulta.
@@ -0,0 +1,65 @@
1
+ # GOLEM — El personaje (`G1_Character`)
2
+
3
+ Referencia de dominio para escribir y leer las fichas de personaje
4
+ (`bible/characters/<slug>.md`). El indexador las ingiere como instancias de
5
+ `G1_Character` del modelo GOLEM. Consúltala desde `bookwright-bible` (al estampar
6
+ las fichas) y desde `bookwright-draft` (para mantener la voz constante).
7
+
8
+ ## Lo platónico vs. lo narrativo
9
+
10
+ GOLEM distingue dos planos del personaje:
11
+
12
+ - **El personaje platónico** (`G0_Character-Stoff`): la identidad estable y
13
+ reconocible que persiste a través de toda la obra y, en teoría, a través de
14
+ distintas versiones de la historia. Es "quién es" con independencia de la
15
+ escena: su nombre, su biografía, su voz.
16
+ - **El personaje narrativo** (manifestaciones en `G5_Narrative_Event` y estados
17
+ `G3_Psychological_State`): cómo aparece y cambia en momentos concretos de la
18
+ trama. Es "cómo está aquí y ahora".
19
+
20
+ La ficha de `bible/characters/` captura sobre todo el plano **platónico**
21
+ (identidad estable). La evolución por escena vive en el manuscrito, en
22
+ `timeline.md` (eventos) y en los arcos del outline. No metas en la ficha datos
23
+ que solo son ciertos en un capítulo concreto: márcalos donde correspondan.
24
+
25
+ ## Contrato del frontmatter
26
+
27
+ El frontmatter de una ficha de personaje admite **únicamente** estas claves de
28
+ nivel superior; cualquier otra genera un aviso del indexador:
29
+
30
+ ```yaml
31
+ name: "Ana Soler" # cadena obligatoria
32
+ born: 1990 # año entero, o se omite la línea
33
+ died: 2031 # año entero, o se omite si sigue viva
34
+ features: ["zurda", "cicatriz en la ceja"] # lista de cadenas
35
+ narrative_roles: ["protagonista", "heroína"] # lista de cadenas
36
+ ```
37
+
38
+ - **`name`** — obligatoria, cadena no vacía. Si falta el dato, escribe el
39
+ marcador **entre comillas**: `name: "[PENDING: ¿Cómo se llama?]"` (sin
40
+ comillas, los corchetes se parsean como lista y la ficha se descarta — ver
41
+ `references/pending-protocol.md`).
42
+ - **`born` / `died`** — año entero o **omitidas**. Nunca un texto ni un
43
+ `[PENDING]`: un valor no entero hace que el indexador descarte el archivo. La
44
+ edad se deriva de `born`/`died` o se cuenta en prosa, jamás como cadena en el
45
+ frontmatter.
46
+ - **`features`** — rasgos distintivos estables (físicos o de carácter), lista de
47
+ cadenas.
48
+ - **`narrative_roles`** — etiquetas de función narrativa (protagonista,
49
+ antagonista, aliado, mentor…), lista de cadenas. Conectan con los vocabularios
50
+ de Propp/Greimas si la constitución los activó.
51
+
52
+ ## El slug
53
+
54
+ El *slug* de un personaje se deriva de su `name` (p. ej. `name: "Ana Soler"` →
55
+ `ana-soler`), **no** del nombre del archivo. Nombra cada
56
+ `bible/characters/<slug>.md` con ese mismo slug para que las referencias desde
57
+ `timeline.md` y `relationships.md` (que listan slugs en `participants`)
58
+ resuelvan correctamente.
59
+
60
+ ## Secciones de cuerpo (de la plantilla)
61
+
62
+ La ficha estampada trae secciones en prosa que **no** se indexan pero anclan al
63
+ personaje: rasgos biográficos, rasgos psicológicos, rasgos físicos, rol
64
+ narrativo, un diálogo de muestra (clave para la voz) y patrones de lenguaje
65
+ corporal. Rellénalas con material del brief; marca `[PENDING: …]` lo que falte.
@@ -0,0 +1,56 @@
1
+ # GOLEM — Eventos y línea de tiempo (`G5_Narrative_Event` vs. `G3_Psychological_State`)
2
+
3
+ Referencia de dominio para `bible/timeline.md`. La consultan `bookwright-bible`
4
+ (al poblar la cronología) y `bookwright-continuity` (al verificar la coherencia
5
+ temporal del manuscrito frente a la biblia).
6
+
7
+ ## Evento vs. estado psicológico
8
+
9
+ GOLEM separa dos cosas que es fácil confundir:
10
+
11
+ - **`G5_Narrative_Event`** — un **hecho** discreto que ocurre en la historia y
12
+ hace avanzar la trama: "la caída del puente de Ardía", "el pacto en la torre".
13
+ Tiene participantes y ocupa un punto (o tramo) en la cronología. Es lo que se
14
+ registra en `timeline.md`.
15
+ - **`G3_Psychological_State`** — el **estado interior** de un personaje en un
16
+ momento dado: "Ana, paralizada por la culpa tras el pacto". No es un hecho del
17
+ mundo, es una condición de la mente. **No** va en `timeline.md`: vive en la
18
+ ficha del personaje (rasgos psicológicos), en los arcos del outline y en el
19
+ manuscrito.
20
+
21
+ Regla práctica al poblar la cronología: si la frase responde a "¿qué **pasó**?",
22
+ es un evento → `timeline.md`. Si responde a "¿cómo **se sentía** alguien?", es un
23
+ estado → ficha/arco, no la cronología.
24
+
25
+ ## Contrato del contenedor `timeline.md`
26
+
27
+ `bible/timeline.md` es un archivo **contenedor indexado**. Su frontmatter lleva
28
+ una única clave de nivel superior, `events:`, una lista de mapas en **orden
29
+ cronológico interno** de la historia:
30
+
31
+ ```yaml
32
+ events:
33
+ - name: "Caída del puente de Ardía"
34
+ participants: ["ana-soler", "marco-vega"]
35
+ - name: "Pacto en la torre"
36
+ participants: ["ana-soler"]
37
+ ```
38
+
39
+ - `name` — obligatorio, cadena no vacía; nombra el hecho.
40
+ - `participants` — opcional; lista de *slugs* de personaje. Cada slug debe
41
+ corresponder a un `bible/characters/<slug>.md` real o aparecerá como referencia
42
+ sin resolver.
43
+ - El **orden de la lista** refleja el orden cronológico interno (no
44
+ necesariamente el orden de narración, que puede saltar).
45
+ - **Mantén `events:` como única clave de nivel superior** del frontmatter; otra
46
+ clave dispara un aviso del indexador.
47
+ - El cuerpo en prosa ("notas de cronología") ancla el marco temporal global
48
+ (época, duración, saltos); no se indexa.
49
+
50
+ ## Cronología interna vs. orden de narración
51
+
52
+ `timeline.md` ordena los hechos según ocurren **dentro** del mundo de la obra.
53
+ El orden en que el lector los descubre (analepsis, estructura no lineal) se
54
+ decide en `outline/structure.md`. No fuerces el orden de narración sobre la
55
+ cronología: son dos ejes distintos y `bookwright-continuity` los compara por
56
+ separado.
@@ -0,0 +1,53 @@
1
+ # GOLEM — Relaciones sociales (`G4_Social_Relationship`, `G6_Relationship_Role`)
2
+
3
+ Referencia de dominio para `bible/relationships.md`. La consultan
4
+ `bookwright-bible` (al poblar los vínculos) y `bookwright-continuity` (al razonar
5
+ sobre la coherencia de las relaciones frente al manuscrito).
6
+
7
+ ## Modelado reificado del vínculo
8
+
9
+ En GOLEM una relación social **no** es una arista simple "A quiere a B". Se
10
+ *reifica*: la relación es una entidad de pleno derecho (`G4_Social_Relationship`)
11
+ que conecta a dos o más participantes, y cada participante entra en ella a través
12
+ de un **rol** (`G6_Relationship_Role`). Esto permite que una misma relación
13
+ tenga roles asimétricos (mentor ↔ aprendiz, acreedor ↔ deudor) y que evolucione
14
+ sin perder identidad.
15
+
16
+ - **`G4_Social_Relationship`** — el vínculo en sí: "lealtad fracturada",
17
+ "rivalidad heredada". Tiene nombre y participantes.
18
+ - **`G6_Relationship_Role`** — la posición que ocupa cada participante dentro de
19
+ ese vínculo. Captura la asimetría: en una relación de deuda, uno es acreedor y
20
+ otro deudor.
21
+
22
+ Lo que importa al escribir la biblia: nombra el **vínculo** por su naturaleza
23
+ ("Lealtad fracturada"), no por las personas, y deja que los participantes y sus
24
+ roles se expresen por separado.
25
+
26
+ ## Contrato del contenedor `relationships.md`
27
+
28
+ `bible/relationships.md` es un archivo **contenedor indexado**. Su frontmatter
29
+ lleva una única clave de nivel superior, `relationships:`, una lista de mapas:
30
+
31
+ ```yaml
32
+ relationships:
33
+ - name: "Lealtad fracturada"
34
+ participants: ["ana-soler", "marco-vega"]
35
+ - name: "Rivalidad heredada"
36
+ participants: ["marco-vega", "elsa-roan"]
37
+ ```
38
+
39
+ - `name` — obligatorio; nombra la **naturaleza** del vínculo, no a las personas.
40
+ - `participants` — lista de *slugs* de personaje; cada slug debe existir como
41
+ `bible/characters/<slug>.md` o aparecerá como referencia sin resolver.
42
+ - **Mantén `relationships:` como única clave de nivel superior** del
43
+ frontmatter. Cualquier otra clave dispara un aviso del indexador.
44
+ - El cuerpo en prosa ("mapa de tensiones") describe cómo evolucionan las
45
+ alianzas y conflictos; no se indexa.
46
+
47
+ ## Roles asimétricos en prosa
48
+
49
+ El frontmatter v0 captura el vínculo y sus participantes; la asimetría de roles
50
+ (quién es mentor, quién aprendiz) y su evolución se narran en el cuerpo en prosa
51
+ de `relationships.md` y en los arcos del outline, hasta que un manejador de roles
52
+ explícito llegue en una iteración posterior. No inventes claves de frontmatter
53
+ para los roles: descríbelos en prosa.
@@ -0,0 +1,57 @@
1
+ # Greimas — El modelo actancial
2
+
3
+ Referencia de dominio para la estructura. La consultan `bookwright-outline` (al
4
+ articular el motor del conflicto) y `bookwright-scenes` (al ubicar cada escena en
5
+ el eje de fuerzas). Úsala **solo** si la constitución activó el vocabulario de
6
+ Greimas en "Vocabularios activos"; si no, es material de consulta opcional.
7
+
8
+ ## Qué aporta Greimas
9
+
10
+ Algirdas Julien Greimas abstrajo las esferas de acción de Propp en un modelo más
11
+ general y aplicable a cualquier relato: el **modelo actancial**. Un *actante* no
12
+ es un personaje, es una **función estructural** dentro de la dinámica del relato.
13
+ Un personaje puede encarnar varios actantes; un actante puede repartirse entre
14
+ varios personajes, una colectividad, un objeto o una idea abstracta (la
15
+ justicia, el deber).
16
+
17
+ Su valor para Bookwright: revela el **motor del conflicto** de un vistazo y
18
+ expone desequilibrios (un Sujeto sin Oponente real, un Objeto que a nadie le
19
+ importa de verdad).
20
+
21
+ ## Los seis actantes en tres ejes
22
+
23
+ El modelo organiza seis actantes en tres parejas de oposición:
24
+
25
+ ### Eje del deseo (Sujeto → Objeto)
26
+
27
+ - **Sujeto** — quien desea y persigue una meta (a menudo el protagonista).
28
+ - **Objeto** — lo deseado: una persona, una cosa, un estado del mundo, un valor.
29
+ Es el motor de la acción: define qué quiere el Sujeto.
30
+
31
+ ### Eje de la comunicación (Destinador → Destinatario)
32
+
33
+ - **Destinador (sender)** — la fuerza que motiva o encomienda la búsqueda y, al
34
+ final, sanciona el resultado: un personaje, una institución, una ley moral, el
35
+ destino.
36
+ - **Destinatario (receiver)** — quien se beneficia de que el Objeto se alcance
37
+ (a veces coincide con el propio Sujeto).
38
+
39
+ ### Eje del poder (Ayudante ↔ Oponente)
40
+
41
+ - **Ayudante (helper)** — lo que facilita la obtención del Objeto: aliados,
42
+ recursos, cualidades del Sujeto.
43
+ - **Oponente (opponent)** — lo que la obstaculiza: el antagonista, pero también
44
+ miedos internos, circunstancias, el tiempo.
45
+
46
+ ## Cómo usarlo al escribir
47
+
48
+ Para una obra o un arco, completa el esquema: *¿Quién es el Sujeto? ¿Qué Objeto
49
+ persigue? ¿Quién/qué se lo encarga y para quién? ¿Qué lo ayuda y qué se le
50
+ opone?* Si una casilla queda vacía o difusa, suele señalar un problema
51
+ estructural antes de escribir una sola escena. A nivel de escena, identifica qué
52
+ fuerzas actanciales están en juego: una escena nítida casi siempre enfrenta a un
53
+ Sujeto con un Oponente respecto a un Objeto concreto.
54
+
55
+ El modelo dialoga con las esferas de Propp (ver `references/propp-functions.md`):
56
+ el Sujeto ≈ héroe, el Oponente ≈ villano, el Ayudante ≈ auxiliar/donante, el
57
+ Destinador ≈ mandatario. Greimas es la lectura abstracta; Propp, la concreta.
@@ -0,0 +1,72 @@
1
+ # Protocolo `[PENDING: …]` — marcar y continuar vs. detenerse y preguntar
2
+
3
+ Esta es la regla compartida que todos los comandos generativos
4
+ (`bookwright-constitution`, `bookwright-bible`, `bookwright-outline`,
5
+ `bookwright-scenes`, `bookwright-draft`, `bookwright-synopsis`,
6
+ `bookwright-research`) siguen al encontrar información que el brief o los
7
+ artefactos existentes no proporcionan.
8
+ Es la única fuente de verdad de esta decisión: los cuerpos de los comandos
9
+ enlazan aquí en lugar de repetir la regla.
10
+
11
+ ## El token
12
+
13
+ El marcador de relleno es exactamente `[PENDING: <pregunta en español>]`:
14
+
15
+ - El token `PENDING` se escribe **en inglés** y en mayúsculas.
16
+ - La pregunta que sigue se escribe **en español**, redactada como una pregunta
17
+ concreta dirigida al autor (no una etiqueta genérica como `[PENDING]` a secas).
18
+ - Ejemplo: `[PENDING: ¿Desde qué distancia narrativa se cuenta la obra?]`.
19
+
20
+ Este es el mismo marcador que estampan las plantillas de la iteración 7, que
21
+ busca el barrido de centinelas y que evalúa `bookwright-checklist`. No inventes
22
+ variantes (`[PENDIENTE]`, `TODO`, `???`): romperían ese acuerdo.
23
+
24
+ ## Marcar y continuar (caso por defecto)
25
+
26
+ Cuando el material disponible simplemente **carece** de un dato, escribe el
27
+ `[PENDING: …]` en su sitio y **continúa** con el resto del trabajo. No te
28
+ detengas a preguntar. Ejemplos de "carece de un dato":
29
+
30
+ - El brief no menciona el año de nacimiento de un personaje secundario.
31
+ - No se indica el tono exacto del registro coloquial.
32
+ - Falta el nombre de un lugar que aún no es relevante para la trama.
33
+
34
+ La obra puede avanzar con estos huecos marcados; el autor los resolverá después,
35
+ y una nueva invocación del comando los rellenará (regla de actualización en
36
+ sitio).
37
+
38
+ ## Detenerse y preguntar (excepción)
39
+
40
+ Detente y consulta al autor **solo** cuando continuar exigiría inventar *canon
41
+ estructural* (load-bearing): un dato del que dependen otras decisiones y que no
42
+ puede derivarse de los artefactos existentes, o que **contradiría** algo ya
43
+ escrito. Ejemplos:
44
+
45
+ - La motivación central del protagonista (de ella cuelgan arco, escenas y
46
+ desenlace).
47
+ - El modelo estructural de la obra cuando el outline depende por completo de él.
48
+ - Un hecho nuevo que chocaría con la constitución o con una ficha ya resuelta.
49
+
50
+ En estos casos, inventar sería peor que un hueco: propagaría una decisión
51
+ arbitraria por toda la obra. Formula una pregunta breve y precisa, y espera la
52
+ respuesta antes de escribir ese fragmento.
53
+
54
+ Regla mnemónica: **si el hueco solo te falta, márcalo; si rellenarlo te obliga a
55
+ decidir el rumbo de la obra, pregunta.**
56
+
57
+ ## Comillas en YAML (campos de tipo cadena)
58
+
59
+ Cuando un `[PENDING: …]` cae dentro de un campo de frontmatter **de tipo
60
+ cadena** —el caso típico es `name:` en una ficha de personaje o de escenario—
61
+ debe ir **entre comillas**:
62
+
63
+ ```yaml
64
+ name: "[PENDING: ¿Cómo se llama el personaje?]"
65
+ ```
66
+
67
+ Sin comillas, los corchetes `[ … ]` se interpretan como una **lista YAML**: el
68
+ valor deja de ser una cadena, el indexador descarta la ficha y el dato se
69
+ pierde silenciosamente. Esto **solo** aplica a campos de cadena del frontmatter;
70
+ en el cuerpo en prosa el marcador se escribe sin comillas
71
+ (`[PENDING: ¿…?]`). Nunca pongas un `[PENDING]` en un campo numérico (`born`,
72
+ `died`): déjalo omitido en su lugar.
@@ -0,0 +1,54 @@
1
+ # Propp — Funciones narrativas y dramatis personae
2
+
3
+ Referencia de dominio para la estructura. La consultan `bookwright-outline` (al
4
+ montar arcos y estructura) y `bookwright-scenes` (al asignar a cada escena su
5
+ función narrativa). Úsala **solo** si la constitución activó el vocabulario de
6
+ Propp en "Vocabularios activos"; si no, es material de consulta opcional.
7
+
8
+ ## Qué aporta Propp
9
+
10
+ Vladimir Propp analizó el cuento maravilloso y observó que, bajo la variedad
11
+ superficial, las historias reutilizan un repertorio limitado de **funciones**:
12
+ unidades de acción definidas por su papel en el desarrollo de la trama, no por
13
+ quién las ejecuta. Su valor para Bookwright es doble: dar a cada escena una
14
+ **función** identificable (que justifica su existencia) y detectar huecos
15
+ estructurales (una promesa sin pago, un villano sin fechoría).
16
+
17
+ ## Las funciones (repertorio condensado)
18
+
19
+ Propp enumera 31 funciones que tienden a aparecer en orden. Condensadas en sus
20
+ movimientos esenciales:
21
+
22
+ 1. **Preparación** — alejamiento, prohibición, transgresión, primer daño o
23
+ carencia que pone la historia en marcha (la *fechoría* o la *carencia*).
24
+ 2. **Complicación** — el héroe se entera, decide actuar y parte; aparece el
25
+ donante, que lo somete a una prueba.
26
+ 3. **Transferencia** — el héroe recibe un auxiliar mágico u objeto y se traslada
27
+ al lugar de la prueba decisiva.
28
+ 4. **Combate** — enfrentamiento con el antagonista, marca o herida, victoria,
29
+ reparación del daño/carencia inicial.
30
+ 5. **Regreso** — vuelta, persecución, socorro; a veces llegada de incógnito y
31
+ pretensiones de un falso héroe.
32
+ 6. **Reconocimiento** — tarea difícil, su resolución, reconocimiento del héroe,
33
+ desenmascaramiento del falso héroe, castigo y recompensa (boda/ascenso).
34
+
35
+ Cada escena debería poder etiquetarse con la función que cumple. Una escena que
36
+ no avanza ninguna función suele ser una escena que sobra.
37
+
38
+ ## Dramatis personae (las siete esferas de acción)
39
+
40
+ Propp agrupa a los personajes por la **esfera de acción** que ocupan, no por su
41
+ identidad. Un mismo personaje puede cambiar de esfera; varias personas pueden
42
+ compartir una:
43
+
44
+ - **Héroe** — quien repara la carencia o vence; sigue el recorrido central.
45
+ - **Antagonista / villano** — causa la fechoría y se opone al héroe.
46
+ - **Donante** — provee el medio (objeto, saber) tras una prueba.
47
+ - **Auxiliar** — ayuda al héroe en la misión.
48
+ - **Princesa (y su padre)** — el objeto buscado y quien fija/recompensa la tarea.
49
+ - **Mandatario** — quien envía al héroe a la misión.
50
+ - **Falso héroe** — reclama el mérito ajeno; será desenmascarado.
51
+
52
+ Estas esferas conversan con `narrative_roles` en las fichas de personaje y con el
53
+ modelo actancial de Greimas (ver `references/greimas-actants.md`), que ofrece una
54
+ lectura más abstracta de las mismas fuerzas.
@@ -0,0 +1,136 @@
1
+ # Formato de `bible/research/` — el contrato que el grafo lee
2
+
3
+ Esta es la referencia de formato para los archivos que escribe
4
+ `bookwright-research`. El lector (`bookwright graph build`) es **estricto**: una
5
+ violación marcada *fatal* aborta el build con un `ResearchError` y no produce
6
+ grafo. Escribe exactamente esta forma; no inventes claves ni valores nuevos.
7
+
8
+ Orden de proceso (determinista): `sources.md` → cada `<tema>.md` (orden
9
+ alfabético) → `_index.md`.
10
+
11
+ ## Vocabularios controlados
12
+
13
+ - `type` ∈ `{primaria, secundaria, oficial, académica, periodística, testimonial}`
14
+ - `reliability` ∈ `{alta, media, baja}`
15
+
16
+ Un `type` o `reliability` fuera de vocabulario es **fatal** (el error nombra el
17
+ valor).
18
+
19
+ ## `sources.md` — el registro de fuentes
20
+
21
+ Clave de frontmatter `sources:` → una lista de mappings. Por cada fuente:
22
+
23
+ | Clave | Obligatoria | Tipo | Notas |
24
+ |---|---|---|---|
25
+ | `name` | ✅ | str | único por *slug* en el archivo (un *slug* duplicado es **fatal**) |
26
+ | `reference` | ✅ | str | localizador de la cita (signatura, URL, tomo/folio) |
27
+ | `author` | ✅ | str | autor u organismo responsable |
28
+ | `original_language` | ✅ | str | código ISO 639-1 (`es`, `de`, `fr`, …) |
29
+ | `type` | ✅ | enum | ver vocabulario |
30
+ | `reliability` | ✅ | enum | ver vocabulario |
31
+ | `reliability_justification` | ✅ | str | no vacío: por qué esa fiabilidad |
32
+ | `access_date` | ✅ | fecha | ISO `YYYY-MM-DD` |
33
+ | `original_quote` | ✅ | str | cita literal en la lengua original |
34
+ | `translation` | condicional | str | **obligatoria si** `original_language` ≠ idioma del libro; **se omite** cuando coinciden |
35
+
36
+ - Falta una faceta obligatoria → **fatal** (el error nombra la faceta).
37
+ - Regla de traducción: una fuente en lengua distinta a la del libro **sin**
38
+ `translation` es **fatal**. Si coinciden, no pongas `translation`.
39
+
40
+ Ejemplo (libro en `es`, fuente en `de`):
41
+
42
+ ```yaml
43
+ ---
44
+ sources:
45
+ - name: "Kriegstagebuch des OKW, Bd. III"
46
+ reference: "BA-MA RH 2/..., ff. 12-18"
47
+ author: "Oberkommando der Wehrmacht"
48
+ original_language: de
49
+ type: primaria
50
+ reliability: alta
51
+ reliability_justification: "Registro oficial contemporáneo."
52
+ access_date: 2026-06-04
53
+ original_quote: "Die Nachschublage an der Ostfront ..."
54
+ translation: "La situación de abastecimiento en el frente oriental ..."
55
+ ---
56
+ ```
57
+
58
+ ## `<tema>.md` — hallazgos y anclas
59
+
60
+ Frontmatter con `findings:` y `anchors:` (ambas listas, opcionales). El nombre de
61
+ archivo es el *slug* del título del tema; conserva el título humano como
62
+ `# Encabezado` y como prosa legible en el cuerpo (el cuerpo no se indexa).
63
+
64
+ ### `findings[]`
65
+
66
+ | Clave | Obligatoria | Tipo | Notas |
67
+ |---|---|---|---|
68
+ | `id` | ✅ | str | no vacío; único en el archivo; es el blanco de las anclas |
69
+ | `claim` | condicional | str | obligatoria salvo que `open: true` |
70
+ | `sources` | condicional | list[str] | ≥1 nombre de fuente que **resuelva** en `sources.md`, salvo `open: true` (no resolver es **fatal**) |
71
+ | `asserted_by` | ❌ | str | por defecto `"author"` |
72
+ | `bears_on` | ❌ | str | nombre de entidad narrativa; si no resuelve, **aviso suave** |
73
+ | `open` | ❌ | bool | por defecto `false` |
74
+
75
+ - Un hallazgo no abierto sin `claim` **o** sin ≥1 fuente que resuelva es **fatal**.
76
+ - Cuando las fuentes discrepen, escribe **dos hallazgos**, cada uno con su propia
77
+ fuente; nunca los fundas en uno solo.
78
+
79
+ ### `anchors[]`
80
+
81
+ | Clave | Obligatoria | Tipo | Notas |
82
+ |---|---|---|---|
83
+ | `promotes` | ✅ | str | un `id` de hallazgo **de este archivo** (desconocido = **fatal**) |
84
+ | `constrains` | ✅ | str | nombre de entidad narrativa, o el literal `"timeline"`; ausente = **fatal**; entidad que no resuelve = **aviso suave** |
85
+ | `begin` | ❌ | int | año (solo entero; otra cosa = **fatal**) |
86
+ | `end` | ❌ | int | año |
87
+ | `date` | ❌ | int | año; **mutuamente excluyente** con `begin`/`end` (combinarlos = **fatal**) |
88
+
89
+ Promueve a ancla **solo** si la mejor fuente del hallazgo alcanza el umbral
90
+ `[research].min_reliability_for_anchor` del manifiesto (`alta` > `media` > `baja`).
91
+
92
+ ```yaml
93
+ ---
94
+ findings:
95
+ - id: f1
96
+ claim: "El ferrocarril de vía estrecha limitaba el tonelaje diario."
97
+ sources: ["Kriegstagebuch des OKW, Bd. III"]
98
+ bears_on: "Wehrmacht"
99
+ - id: q-ruta-suministro
100
+ open: true
101
+ anchors:
102
+ - promotes: f1
103
+ constrains: "Wehrmacht"
104
+ begin: 1943
105
+ end: 1943
106
+ ---
107
+ ```
108
+
109
+ ## `_index.md` — preguntas abiertas y mapa de temas
110
+
111
+ Frontmatter con `open_questions:` → una lista mapeada como **hallazgos abiertos**
112
+ (`id` obligatorio; `claim`/`sources` opcionales). El cuerpo en prosa (mapa de
113
+ temas, lista global de preguntas abiertas) es para humanos y **no se indexa**.
114
+
115
+ ```yaml
116
+ ---
117
+ open_questions:
118
+ - id: q-calibre-via
119
+ claim: "¿Qué ancho de vía tenía el ramal?"
120
+ ---
121
+ # Índice de investigación
122
+ ## Temas
123
+ - [Logística de la Wehrmacht en 1943](logistica-de-la-wehrmacht-en-1943.md)
124
+ ```
125
+
126
+ ## Suave vs. fatal — resumen
127
+
128
+ - **Fatal** (`ResearchError`, sin grafo): YAML mal formado; falta una faceta de
129
+ fuente; vocabulario desconocido; nombre de fuente duplicado; hallazgo no abierto
130
+ sin `claim`/fuente; nombre de fuente que no resuelve; ancla que promueve un
131
+ hallazgo desconocido; falta `constrains`; año no entero; `date` junto a
132
+ `begin`/`end`; incumplir la regla de traducción.
133
+ - **Suave** (`ResearchWarning`, el grafo se construye igual): un `bears_on` o
134
+ `constrains` que no resuelve en la biblia (se omite la arista; la verificación
135
+ de existencia es trabajo de un validador posterior).
136
+ - **Vacío/ausente** `bible/research/` → cero entidades, nunca falla.
@@ -0,0 +1,23 @@
1
+ # Bookwright project cache (regenerated by `bookwright graph build`)
2
+ .bookwright/cache/
3
+
4
+ # Python artifacts
5
+ *.pyc
6
+ *.pyo
7
+ __pycache__/
8
+ *.egg-info/
9
+ build/
10
+ dist/
11
+
12
+ # Virtual environments
13
+ .venv/
14
+ venv/
15
+
16
+ # Environment files
17
+ .env
18
+ .env.*
19
+ !.env.example
20
+
21
+ # OS cruft
22
+ .DS_Store
23
+ Thumbs.db