claude-code-arcane 1.4.0 → 2.1.0
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.
- package/CHANGELOG.md +55 -0
- package/README.md +5 -4
- package/dist/cli.js +2 -0
- package/docs/SKILLS-CATALOG.md +30 -3
- package/docs/USER-GUIDE.md +2 -2
- package/docs/coding-standards.md +26 -0
- package/package.json +2 -1
- package/profiles/job-hunt.yaml +12 -2
- package/profiles/second-brain.yaml +37 -0
- package/rules/drafter-reviewer.md +39 -0
- package/rules/vault-conventions.md +144 -0
- package/skills/brain-dump/SKILL.md +53 -0
- package/skills/cold-outreach/SKILL.md +10 -10
- package/skills/cold-outreach/references/recruiter-playbook.md +5 -5
- package/skills/cover-letter/SKILL.md +8 -8
- package/skills/cv-ats-export/SKILL.md +19 -6
- package/skills/cv-ats-export/scripts/cv_export.py +49 -4
- package/skills/cv-ats-export/scripts/verify_pdf.py +90 -0
- package/skills/cv-tailor/SKILL.md +7 -7
- package/skills/cv-tailor/references/ats-keywords.md +9 -9
- package/skills/hub-note/SKILL.md +68 -0
- package/skills/interview-prep/SKILL.md +7 -7
- package/skills/interview-prep/references/star-framework.md +10 -10
- package/skills/job-aplicar/SKILL.md +88 -0
- package/skills/job-hunt/SKILL.md +20 -13
- package/skills/job-hunt/references/templates/Aplicacion.md +6 -2
- package/skills/job-hunt/references/templates/CV Custom.md +1 -1
- package/skills/job-hunt/references/templates/Contacto.md +1 -1
- package/skills/job-hunt/references/templates/Dashboard.md +19 -15
- package/skills/job-hunt/references/templates/Perfil.md +2 -2
- package/skills/job-outcome/SKILL.md +55 -0
- package/skills/job-scrape/SKILL.md +95 -0
- package/skills/job-scrape/references/dedup-playbook.md +25 -0
- package/skills/job-scrape/references/getonbrd-cli.md +62 -0
- package/skills/job-scrape/references/getonbrd-urls.md +37 -0
- package/skills/job-scrape/references/linkedin-cli.md +64 -0
- package/skills/job-scrape/references/linkedin-urls.md +42 -0
- package/skills/job-scrape/references/seen_jobs.schema.json +68 -0
- package/skills/job-scrape/scripts/getonbrd_search.py +501 -0
- package/skills/job-scrape/scripts/linkedin_search.py +428 -0
- package/skills/job-search/SKILL.md +22 -19
- package/skills/job-search/references/scoring-rubric.md +8 -8
- package/skills/job-upskill/SKILL.md +58 -0
- package/skills/linkedin-optimize/SKILL.md +5 -5
- package/skills/master-profile/SKILL.md +17 -17
- package/skills/network-map/SKILL.md +7 -7
- package/skills/obsidian-bases/SKILL.md +85 -0
- package/skills/obsidian-bases/references/bases-syntax.md +123 -0
- package/skills/obsidian-canvas/SKILL.md +91 -0
- package/skills/obsidian-markdown/SKILL.md +110 -0
- package/skills/pdf-generator/scripts/fill_inspect.py +2 -0
- package/skills/pdf-generator/scripts/render_body.py +2 -0
- package/skills/personal-brand/SKILL.md +10 -10
- package/skills/personal-brand/references/post-pillars.md +14 -14
- package/skills/portfolio-site/SKILL.md +11 -11
- package/skills/review-dump/SKILL.md +108 -0
- package/skills/review-monthly/SKILL.md +56 -0
- package/skills/review-weekly/SKILL.md +91 -0
- package/skills/second-brain/SKILL.md +211 -0
- package/skills/second-brain/hooks/hooks.json +16 -0
- package/skills/second-brain/hooks/validate-note.sh +85 -0
- package/skills/second-brain/references/cross-project.md +57 -0
- package/skills/second-brain/references/templates/Atomic.md +22 -0
- package/skills/second-brain/references/templates/Daily.md +25 -0
- package/skills/second-brain/references/templates/Dashboard.base +70 -0
- package/skills/second-brain/references/templates/Dump.md +11 -0
- package/skills/second-brain/references/templates/Hub.md +22 -0
- package/skills/second-brain/references/templates/Monthly.md +29 -0
- package/skills/second-brain/references/templates/Weekly.md +29 -0
- package/skills/second-brain/references/templates/codebases.md +37 -0
- package/skills/second-brain/references/templates/hot.md +37 -0
- package/skills/second-brain/references/templates/vault-CLAUDE.md +127 -0
- package/skills/vault-audit/SKILL.md +72 -0
- package/skills/vault-audit/scripts/vault_audit.py +539 -0
- package/skills/vault-clip/SKILL.md +73 -0
- package/skills/vault-recall/SKILL.md +82 -0
- package/skills/vault-recall/scripts/vault_index.py +626 -0
- package/skills/vault-tidy/SKILL.md +76 -0
- package/skills/xlsx-generator/scripts/formula_check.py +2 -0
- package/skills/xlsx-generator/scripts/libreoffice_recalc.py +2 -0
- package/skills/xlsx-generator/scripts/xlsx_add_column.py +2 -0
- package/skills/xlsx-generator/scripts/xlsx_insert_row.py +2 -0
- package/skills/xlsx-generator/scripts/xlsx_reader.py +2 -0
- package/skills/zettel/SKILL.md +66 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Recruiter / Hiring Manager Playbook
|
|
2
2
|
|
|
3
|
-
Plantillas y psicología para outreach de candidato. Adaptá siempre la primera línea
|
|
3
|
+
Plantillas y psicología para outreach de candidato. Adaptá siempre la primera línea - las plantillas son esqueleto, no copy-paste.
|
|
4
4
|
|
|
5
5
|
## Por qué responden (y por qué no)
|
|
6
6
|
|
|
7
|
-
Responden cuando: el mensaje es corto, claro sobre el fit, fácil de responder, y se nota que es para *ellos*. No responden cuando: es genérico, largo, pide demasiado de entrada, o suena desesperado. El recruiter recibe decenas por día
|
|
7
|
+
Responden cuando: el mensaje es corto, claro sobre el fit, fácil de responder, y se nota que es para *ellos*. No responden cuando: es genérico, largo, pide demasiado de entrada, o suena desesperado. El recruiter recibe decenas por día - el filtro es "¿esto me ahorra trabajo o me lo agrega?".
|
|
8
8
|
|
|
9
9
|
## Plantillas
|
|
10
10
|
|
|
@@ -37,14 +37,14 @@ Hola {nombre}, me interesa mucho {empresa/área}. Vengo de {1 cosa}.
|
|
|
37
37
|
Me encantaría conectar y, si surge, charlar sobre {rol/equipo}.
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
### 5. Follow-up 1 (día 4
|
|
40
|
+
### 5. Follow-up 1 (día 4-5) - con valor nuevo
|
|
41
41
|
```
|
|
42
42
|
Hola {nombre}, te escribo para reafirmar mi interés en {rol}.
|
|
43
43
|
Sumo un dato: {proyecto/idea relevante para su producto}.
|
|
44
44
|
Quedo a disposición para lo que necesiten del proceso.
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
### 6. Follow-up 2 (día 10
|
|
47
|
+
### 6. Follow-up 2 (día 10-12) - cierre digno
|
|
48
48
|
```
|
|
49
49
|
Hola {nombre}, entiendo que están con mucho.
|
|
50
50
|
Dejo la puerta abierta por si avanza {rol}; me encantaría sumar.
|
|
@@ -55,7 +55,7 @@ Dejo la puerta abierta por si avanza {rol}; me encantaría sumar.
|
|
|
55
55
|
|
|
56
56
|
- Máximo 2 follow-ups. Después, soltar.
|
|
57
57
|
- Cada follow-up agrega algo (no "¿novedades?").
|
|
58
|
-
- Espaciar 4
|
|
58
|
+
- Espaciar 4-5 días. Nunca el mismo día ni días consecutivos.
|
|
59
59
|
- Registrar cada toque en la nota de `05-Contactos/`.
|
|
60
60
|
|
|
61
61
|
## Tono
|
|
@@ -7,9 +7,9 @@ user-invocable: true
|
|
|
7
7
|
allowed-tools: Read, Glob, Grep, Write, Edit, WebFetch
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
# Cover Letter
|
|
10
|
+
# Cover Letter - Mensaje de aplicación de élite
|
|
11
11
|
|
|
12
|
-
Escribís cover letters y mensajes de aplicación **concisos, seguros y custom**
|
|
12
|
+
Escribís cover letters y mensajes de aplicación **concisos, seguros y custom** - que suenan a una persona que entendió el rol y la empresa, no a una plantilla. El objetivo: que el lector quiera leer el CV.
|
|
13
13
|
|
|
14
14
|
## Inputs
|
|
15
15
|
|
|
@@ -20,19 +20,19 @@ Escribís cover letters y mensajes de aplicación **concisos, seguros y custom**
|
|
|
20
20
|
|
|
21
21
|
## Principios
|
|
22
22
|
|
|
23
|
-
- **Una página máximo; idealmente 150
|
|
23
|
+
- **Una página máximo; idealmente 150-250 palabras** para mensajes, 250-350 para carta formal.
|
|
24
24
|
- **El primer renglón gana o pierde.** Nada de "I am writing to apply for…". Abrí con un gancho específico: un logro relevante, un punto de conexión con la empresa, o por qué este rol te mueve.
|
|
25
|
-
- **Mostrá fit, no historia.** 1
|
|
25
|
+
- **Mostrá fit, no historia.** 1-2 logros que mapean directo a lo que piden, con número.
|
|
26
26
|
- **Específico de la empresa.** Una frase que demuestre que investigaste (producto, valor, problema que resuelven). Si la podés pegar en otra aplicación, no sirve.
|
|
27
27
|
- **Confiado, no arrogante; cálido, no servil.** Ni "would be honored", ni "I'm the best candidate".
|
|
28
28
|
- **CTA simple al final.** Disponibilidad / ganas de charlar, sin rogar.
|
|
29
29
|
|
|
30
30
|
## Estructura (carta formal)
|
|
31
31
|
|
|
32
|
-
1. **Hook**
|
|
33
|
-
2. **Fit**
|
|
34
|
-
3. **Empresa**
|
|
35
|
-
4. **Cierre**
|
|
32
|
+
1. **Hook** - gancho específico (logro o conexión real).
|
|
33
|
+
2. **Fit** - 1-2 logros mapeados a must-haves del JD, con métrica.
|
|
34
|
+
3. **Empresa** - por qué *esta* empresa/rol (research real).
|
|
35
|
+
4. **Cierre** - CTA breve + gracias.
|
|
36
36
|
|
|
37
37
|
## Estructura (mensaje corto / LinkedIn / email)
|
|
38
38
|
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cv-ats-export
|
|
3
|
-
description: "Export a Markdown CV to an ATS-compliant PDF (single column, selectable text, A4) using headless Chrome/Edge
|
|
3
|
+
description: "Export a Markdown CV to an ATS-compliant PDF (single column, selectable text, A4) using headless Chrome/Edge - no Obsidian or design tool needed. Triggers: exportar CV a PDF, generar PDF del CV, CV ATS PDF, convertir CV markdown a PDF, imprimir CV."
|
|
4
4
|
argument-hint: "[cv-name | all] [--workspace <path>]"
|
|
5
5
|
category: "career"
|
|
6
6
|
user-invocable: true
|
|
7
7
|
allowed-tools: Read, Glob, Grep, Bash, Write
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
# CV ATS Export
|
|
10
|
+
# CV ATS Export - Markdown → PDF ATS-compliant
|
|
11
11
|
|
|
12
|
-
Convertís un CV en Markdown a un **PDF que pasa filtros ATS**: una sola columna, texto seleccionable (no imagen), A4, tipografía limpia. Usa Chrome o Edge en modo headless
|
|
12
|
+
Convertís un CV en Markdown a un **PDF que pasa filtros ATS**: una sola columna, texto seleccionable (no imagen), A4, tipografía limpia. Usa Chrome o Edge en modo headless - no requiere Obsidian, LaTeX ni herramienta de diseño.
|
|
13
13
|
|
|
14
|
-
El motor es `scripts/cv_export.py
|
|
14
|
+
El motor es `scripts/cv_export.py` + `scripts/verify_pdf.py` (verificación ATS post-export). La primera vez, instalá ambos en el workspace (`tools/`) para que queden versionados con los CVs; o corrélos directo desde el skill (van juntos: `cv_export` importa `verify_pdf` desde su mismo directorio).
|
|
15
15
|
|
|
16
16
|
## Requisitos
|
|
17
17
|
|
|
18
18
|
- **Python 3** en el PATH.
|
|
19
19
|
- **Google Chrome o Microsoft Edge** instalado (el script autodetecta rutas estándar en Windows/macOS/Linux).
|
|
20
|
+
- **`pypdf` (opcional)** para la verificación ATS automática: `pip install pypdf`. Sin pypdf el export funciona igual y reporta `[ATS SKIP]`.
|
|
20
21
|
- CVs en Markdown dentro de `02-CVs/` del career workspace, con headers (`# Nombre`, `## Sección`), bullets y `---` como separadores.
|
|
21
22
|
|
|
22
23
|
## Uso
|
|
@@ -30,6 +31,9 @@ python scripts/cv_export.py "CV - Acme - Backend"
|
|
|
30
31
|
|
|
31
32
|
# Workspace explícito
|
|
32
33
|
python scripts/cv_export.py --workspace ./career-workspace "CV - Acme - Backend"
|
|
34
|
+
|
|
35
|
+
# Saltar la verificación ATS
|
|
36
|
+
python scripts/cv_export.py --no-verify "CV - Acme - Backend"
|
|
33
37
|
```
|
|
34
38
|
|
|
35
39
|
El script:
|
|
@@ -37,6 +41,15 @@ El script:
|
|
|
37
41
|
2. Lee el `.md`, separa frontmatter, convierte el cuerpo a HTML con el CSS ATS embebido.
|
|
38
42
|
3. Imprime a PDF con Chrome/Edge headless (`--headless=new --print-to-pdf`).
|
|
39
43
|
4. Guarda en `02-CVs/exports/`. El nombre sale del frontmatter `archivo_pdf` si existe; si no, del nombre del `.md` (sin el prefijo `CV - `).
|
|
44
|
+
5. **Verifica la capa de texto ATS** con `verify_pdf.py` (pypdf): texto extraíble (mínimo 200 chars), que el nombre del H1 y el email sobrevivan al export, y avisa si supera las 2 páginas. Reporta `[ATS OK]` / `[ATS WARN]` / `[ATS SKIP]`; nunca rompe el export. Se salta con `--no-verify`.
|
|
45
|
+
|
|
46
|
+
Los dos `[ATS SKIP]` son distintos: `verify_pdf.py not found next to cv_export.py` significa que copiaste solo un archivo al workspace (instalar pypdf no cambia nada); `pypdf not installed` es el que se resuelve con `pip install pypdf`.
|
|
47
|
+
|
|
48
|
+
`verify_pdf.py` también funciona standalone para chequear cualquier PDF:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
python scripts/verify_pdf.py "02-CVs/exports/Backend.pdf" --min-chars 200 --max-pages 2 --contains "Jane Doe"
|
|
52
|
+
```
|
|
40
53
|
|
|
41
54
|
## Markdown soportado
|
|
42
55
|
|
|
@@ -51,12 +64,12 @@ El script:
|
|
|
51
64
|
|
|
52
65
|
## Personalizar el estilo
|
|
53
66
|
|
|
54
|
-
El CSS ATS está en la constante `CSS` dentro de `scripts/cv_export.py` (tamaño de fuente, márgenes A4, estilos de h1/h2). Editá ahí si querés ajustar tipografía o espaciado
|
|
67
|
+
El CSS ATS está en la constante `CSS` dentro de `scripts/cv_export.py` (tamaño de fuente, márgenes A4, estilos de h1/h2). Editá ahí si querés ajustar tipografía o espaciado - mantené una sola columna y texto real.
|
|
55
68
|
|
|
56
69
|
## Reglas
|
|
57
70
|
|
|
58
71
|
- No metas tablas, columnas ni imágenes en el CV: rompen el parseo ATS.
|
|
59
|
-
-
|
|
72
|
+
- Atendé los `[ATS WARN]`: un PDF-imagen o sin el nombre/email extraíbles no pasa filtros ATS. Usá `--no-verify` solo para iterar rápido sobre el layout.
|
|
60
73
|
- No commitees PDFs con datos sensibles a un remoto sin confirmación.
|
|
61
74
|
|
|
62
75
|
## Handoff
|
|
@@ -8,6 +8,12 @@ Usage (from anywhere; the script locates the career workspace):
|
|
|
8
8
|
python cv_export.py # all base CVs (CV - *.md)
|
|
9
9
|
python cv_export.py "CV - Acme - Backend" # a single CV (with/without .md)
|
|
10
10
|
python cv_export.py --workspace ./career-workspace "CV - Acme"
|
|
11
|
+
python cv_export.py --no-verify ... # skip the ATS verification
|
|
12
|
+
|
|
13
|
+
After exporting, the PDF text layer is verified with verify_pdf.py (pypdf):
|
|
14
|
+
extractable text, the H1 name and the email must survive the export, and a
|
|
15
|
+
warning is printed above 2 pages. Reports [ATS OK] / [ATS WARN]; if pypdf is
|
|
16
|
+
not installed, [ATS SKIP] without breaking the export.
|
|
11
17
|
|
|
12
18
|
Workspace resolution order:
|
|
13
19
|
1. --workspace <path> flag
|
|
@@ -204,7 +210,41 @@ def find_browser():
|
|
|
204
210
|
return None
|
|
205
211
|
|
|
206
212
|
|
|
207
|
-
def
|
|
213
|
+
def verify_ats(pdf_path, body):
|
|
214
|
+
"""Verify the exported PDF's text layer. Never breaks the export: reports."""
|
|
215
|
+
# Two distinct failures, two distinct messages: verify_pdf.py missing next to
|
|
216
|
+
# this script (installing pypdf would not help) vs pypdf missing, which
|
|
217
|
+
# verify_pdf only imports when it actually reads the PDF.
|
|
218
|
+
try:
|
|
219
|
+
from verify_pdf import verify
|
|
220
|
+
except ImportError:
|
|
221
|
+
print(f" [ATS SKIP] verify_pdf.py not found next to {Path(__file__).name}")
|
|
222
|
+
return
|
|
223
|
+
|
|
224
|
+
contains = []
|
|
225
|
+
m = re.search(r"^#\s+(.+)$", body, re.MULTILINE)
|
|
226
|
+
if m:
|
|
227
|
+
contains.append(re.sub(r"\*|\[|\]\([^)]*\)", "", m.group(1)).strip())
|
|
228
|
+
m = re.search(r"[\w.+-]+@[\w-]+\.[\w.]+", body)
|
|
229
|
+
if m:
|
|
230
|
+
contains.append(m.group(0))
|
|
231
|
+
|
|
232
|
+
try:
|
|
233
|
+
problems = verify(pdf_path, min_chars=200, contains=contains, max_pages=2)
|
|
234
|
+
except ImportError:
|
|
235
|
+
print(" [ATS SKIP] pypdf not installed (pip install pypdf)")
|
|
236
|
+
return
|
|
237
|
+
except Exception as e:
|
|
238
|
+
problems = [f"could not verify: {e}"]
|
|
239
|
+
|
|
240
|
+
if problems:
|
|
241
|
+
for p in problems:
|
|
242
|
+
print(f" [ATS WARN] {p}")
|
|
243
|
+
else:
|
|
244
|
+
print(" [ATS OK] text layer verified (name + email extractable)")
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def export(md_path, browser, cv_dir, export_dir, check_ats=True):
|
|
208
248
|
text = md_path.read_text(encoding="utf-8")
|
|
209
249
|
fm, body = strip_frontmatter(text)
|
|
210
250
|
|
|
@@ -252,12 +292,15 @@ def export(md_path, browser, cv_dir, export_dir):
|
|
|
252
292
|
|
|
253
293
|
size_kb = pdf_path.stat().st_size // 1024
|
|
254
294
|
print(f"[OK] {md_path.name} -> {pdf_path} ({size_kb} KB)")
|
|
295
|
+
if check_ats:
|
|
296
|
+
verify_ats(pdf_path, body)
|
|
255
297
|
return True
|
|
256
298
|
|
|
257
299
|
|
|
258
300
|
def parse_args(argv):
|
|
259
301
|
workspace = None
|
|
260
302
|
names = []
|
|
303
|
+
check_ats = True
|
|
261
304
|
i = 0
|
|
262
305
|
while i < len(argv):
|
|
263
306
|
a = argv[i]
|
|
@@ -266,14 +309,16 @@ def parse_args(argv):
|
|
|
266
309
|
workspace = argv[i] if i < len(argv) else None
|
|
267
310
|
elif a.startswith("--workspace="):
|
|
268
311
|
workspace = a.split("=", 1)[1]
|
|
312
|
+
elif a == "--no-verify":
|
|
313
|
+
check_ats = False
|
|
269
314
|
else:
|
|
270
315
|
names.append(a)
|
|
271
316
|
i += 1
|
|
272
|
-
return workspace, names
|
|
317
|
+
return workspace, names, check_ats
|
|
273
318
|
|
|
274
319
|
|
|
275
320
|
def main():
|
|
276
|
-
workspace, names = parse_args(sys.argv[1:])
|
|
321
|
+
workspace, names, check_ats = parse_args(sys.argv[1:])
|
|
277
322
|
|
|
278
323
|
browser = find_browser()
|
|
279
324
|
if not browser:
|
|
@@ -298,7 +343,7 @@ def main():
|
|
|
298
343
|
print(f"[ERROR] No CVs (CV - *.md) found in {cv_dir}.")
|
|
299
344
|
sys.exit(1)
|
|
300
345
|
|
|
301
|
-
ok = all([export(t, browser, cv_dir, export_dir) for t in targets])
|
|
346
|
+
ok = all([export(t, browser, cv_dir, export_dir, check_ats) for t in targets])
|
|
302
347
|
sys.exit(0 if ok else 1)
|
|
303
348
|
|
|
304
349
|
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""
|
|
2
|
+
verify_pdf.py — Verify that an exported PDF is ATS-compliant.
|
|
3
|
+
|
|
4
|
+
Checks that the PDF has an extractable text layer (not an image), the
|
|
5
|
+
expected page count, and that given strings (name, email) survived the
|
|
6
|
+
export. Adapted from tools/verify_pdf.py of MadsLorentzen/ai-job-search,
|
|
7
|
+
replacing poppler (pdftotext/pdfinfo) with pypdf so it runs on Windows
|
|
8
|
+
without external binaries.
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
python verify_pdf.py <pdf> [--pages N] [--max-pages N] [--min-chars N]
|
|
12
|
+
[--contains TEXT ...]
|
|
13
|
+
|
|
14
|
+
Example:
|
|
15
|
+
python verify_pdf.py "career-workspace/02-CVs/exports/Backend.pdf" \
|
|
16
|
+
--min-chars 200 --contains "Jane Doe"
|
|
17
|
+
|
|
18
|
+
Exit code 0 if all checks pass, 1 if any check fails, 2 if pypdf is missing.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
import argparse
|
|
22
|
+
import sys
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def extract_text(pdf_path):
|
|
27
|
+
"""Return (page_count, normalized_text) of the PDF."""
|
|
28
|
+
from pypdf import PdfReader
|
|
29
|
+
|
|
30
|
+
reader = PdfReader(str(pdf_path))
|
|
31
|
+
text = "\n".join(page.extract_text() or "" for page in reader.pages)
|
|
32
|
+
return len(reader.pages), " ".join(text.split())
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def verify(pdf_path, pages=None, min_chars=1, contains=(), max_pages=None):
|
|
36
|
+
"""Return a list of problems (empty = PDF OK). Raises ImportError without pypdf."""
|
|
37
|
+
pdf_path = Path(pdf_path)
|
|
38
|
+
if not pdf_path.exists():
|
|
39
|
+
return [f"does not exist: {pdf_path}"]
|
|
40
|
+
|
|
41
|
+
n_pages, text = extract_text(pdf_path)
|
|
42
|
+
problems = []
|
|
43
|
+
|
|
44
|
+
if pages is not None and n_pages != pages:
|
|
45
|
+
problems.append(f"has {n_pages} pages (expected {pages})")
|
|
46
|
+
if max_pages is not None and n_pages > max_pages:
|
|
47
|
+
problems.append(f"has {n_pages} pages (ideally 1-{max_pages} for a CV)")
|
|
48
|
+
if len(text) < min_chars:
|
|
49
|
+
problems.append(
|
|
50
|
+
f"text layer has {len(text)} extractable chars (minimum {min_chars}); "
|
|
51
|
+
"likely an image-only PDF that an ATS cannot read"
|
|
52
|
+
)
|
|
53
|
+
for needle in contains:
|
|
54
|
+
if " ".join(needle.split()).lower() not in text.lower():
|
|
55
|
+
problems.append(f'missing required text: "{needle}"')
|
|
56
|
+
|
|
57
|
+
return problems
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def main():
|
|
61
|
+
ap = argparse.ArgumentParser(description="Verify the ATS text layer of a PDF.")
|
|
62
|
+
ap.add_argument("pdf", help="path to the PDF")
|
|
63
|
+
ap.add_argument("--pages", type=int, default=None, help="expected page count")
|
|
64
|
+
ap.add_argument("--min-chars", type=int, default=1, help="minimum extractable chars")
|
|
65
|
+
ap.add_argument("--max-pages", type=int, default=None, help="warn above N pages")
|
|
66
|
+
ap.add_argument(
|
|
67
|
+
"--contains", action="append", default=[], metavar="TEXT",
|
|
68
|
+
help="string that must appear in the text (repeatable)",
|
|
69
|
+
)
|
|
70
|
+
args = ap.parse_args()
|
|
71
|
+
|
|
72
|
+
try:
|
|
73
|
+
problems = verify(
|
|
74
|
+
args.pdf, args.pages, args.min_chars, args.contains, args.max_pages
|
|
75
|
+
)
|
|
76
|
+
except ImportError:
|
|
77
|
+
print("[ERROR] pypdf is missing. Install with: pip install pypdf")
|
|
78
|
+
sys.exit(2)
|
|
79
|
+
|
|
80
|
+
name = Path(args.pdf).name
|
|
81
|
+
if problems:
|
|
82
|
+
for p in problems:
|
|
83
|
+
print(f"[FAIL] {name}: {p}")
|
|
84
|
+
sys.exit(1)
|
|
85
|
+
print(f"[OK] {name}: ATS text layer verified")
|
|
86
|
+
sys.exit(0)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
if __name__ == "__main__":
|
|
90
|
+
main()
|
|
@@ -7,9 +7,9 @@ user-invocable: true
|
|
|
7
7
|
allowed-tools: Read, Glob, Grep, Write, Edit, WebFetch
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
# CV Tailor
|
|
10
|
+
# CV Tailor - Adaptar el CV a la oferta
|
|
11
11
|
|
|
12
|
-
Tomás un job description y el perfil base del usuario, y producís un **CV custom** que matchea con los filtros automáticos (ATS) y con la lectura humana del hiring manager. No reescribís la verdad
|
|
12
|
+
Tomás un job description y el perfil base del usuario, y producís un **CV custom** que matchea con los filtros automáticos (ATS) y con la lectura humana del hiring manager. No reescribís la verdad - la reorganizás y la traducís al vocabulario de la oferta.
|
|
13
13
|
|
|
14
14
|
## Inputs
|
|
15
15
|
|
|
@@ -20,7 +20,7 @@ Tomás un job description y el perfil base del usuario, y producís un **CV cust
|
|
|
20
20
|
## Proceso
|
|
21
21
|
|
|
22
22
|
### 1. Analizar la oferta
|
|
23
|
-
- Extraer **keywords literales** del JD: tecnologías, metodologías, responsabilidades, soft skills, seniority. Literal importa
|
|
23
|
+
- Extraer **keywords literales** del JD: tecnologías, metodologías, responsabilidades, soft skills, seniority. Literal importa - el ATS hace matching de strings (ej: si piden "React.js" no asumas que "React" matchea igual).
|
|
24
24
|
- Detectar **must-have vs nice-to-have**.
|
|
25
25
|
- Detectar **señales de cultura / ángulo** (startup vs enterprise, code-forward, ownership, etc.).
|
|
26
26
|
- Ver `references/ats-keywords.md` para cómo extraer y mapear keywords.
|
|
@@ -38,17 +38,17 @@ Tomás un job description y el perfil base del usuario, y producís un **CV cust
|
|
|
38
38
|
### 4. Score before/after
|
|
39
39
|
- Calcular un **match rate** aproximado: % de keywords/requisitos del JD presentes en el CV, **antes** vs **después** del tailoring.
|
|
40
40
|
- Reportar el delta ("match 48% → 81%") y qué keywords se cubrieron.
|
|
41
|
-
- **Flag de keyword stuffing:** marcar cualquier inserción que a un revisor humano le suene forzada o poco natural
|
|
41
|
+
- **Flag de keyword stuffing:** marcar cualquier inserción que a un revisor humano le suene forzada o poco natural - el objetivo es pasar el ATS *y* leer bien para una persona.
|
|
42
42
|
|
|
43
43
|
### 5. Producir el CV custom
|
|
44
44
|
- Crear/actualizar la nota en `02-CVs/CV - <Empresa> - <Rol>.md` usando el template `CV Custom` (`Templates/CV Custom.md`).
|
|
45
45
|
- Completar frontmatter (`perfil_base`, `aplicacion`, `empresa`, `archivo_pdf`).
|
|
46
|
-
- Documentar las decisiones (keywords, qué se resaltó/bajó) en las secciones del template
|
|
46
|
+
- Documentar las decisiones (keywords, qué se resaltó/bajó) en las secciones del template - sirve para la entrevista y para iterar.
|
|
47
47
|
- El cuerpo del CV en sí debe quedar listo para `/cv-ats-export` (markdown limpio: `# nombre`, `## secciones`, bullets, `---`).
|
|
48
48
|
|
|
49
49
|
## Formato del CV (ATS-friendly)
|
|
50
50
|
|
|
51
|
-
- **Una columna.** Sin tablas, sin cajas de texto, sin columnas
|
|
51
|
+
- **Una columna.** Sin tablas, sin cajas de texto, sin columnas - los ATS las leen mal.
|
|
52
52
|
- Secciones estándar con headers claros: Summary, Experience, Skills, Projects, Education.
|
|
53
53
|
- Fechas consistentes (MM/YYYY).
|
|
54
54
|
- Sin gráficos ni imágenes para el contenido crítico.
|
|
@@ -62,7 +62,7 @@ CV en **inglés** para roles internacionales/remotos globales; **español** si l
|
|
|
62
62
|
|
|
63
63
|
- Nunca inventar experiencia, fechas o métricas. Tailoring = reorganizar y traducir, no mentir.
|
|
64
64
|
- No keyword-stuffing: cada keyword debe vivir en un bullet verdadero.
|
|
65
|
-
- Un CV custom por postulación
|
|
65
|
+
- Un CV custom por postulación - no pisar el perfil base ni el maestro.
|
|
66
66
|
- Después de generar el `.md`, recordar al usuario correr `/cv-ats-export` para el PDF.
|
|
67
67
|
|
|
68
68
|
## Handoff
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# ATS Keywords
|
|
1
|
+
# ATS Keywords - Cómo extraer y mapear
|
|
2
2
|
|
|
3
3
|
Los Applicant Tracking Systems (Greenhouse, Lever, Workday, Workable, etc.) hacen un primer filtro automático antes de que un humano vea el CV. Entender cómo "leen" cambia el resultado.
|
|
4
4
|
|
|
@@ -11,12 +11,12 @@ Los Applicant Tracking Systems (Greenhouse, Lever, Workday, Workable, etc.) hace
|
|
|
11
11
|
|
|
12
12
|
## Extracción de keywords del JD
|
|
13
13
|
|
|
14
|
-
1. **Hard skills / tecnologías**
|
|
15
|
-
2. **Responsabilidades / verbos**
|
|
16
|
-
3. **Metodologías**
|
|
17
|
-
4. **Seniority y años**
|
|
18
|
-
5. **Soft skills explícitos**
|
|
19
|
-
6. **Señales de cultura / frases gatillo**
|
|
14
|
+
1. **Hard skills / tecnologías** - lenguajes, frameworks, DBs, cloud, herramientas. Copiá la forma **literal** (React.js ≠ React ≠ ReactJS para un match exacto; cuando puedas, incluí la variante que usa la oferta).
|
|
15
|
+
2. **Responsabilidades / verbos** - "design REST APIs", "lead a team", "CI/CD pipelines".
|
|
16
|
+
3. **Metodologías** - Agile, Scrum, TDD, clean architecture.
|
|
17
|
+
4. **Seniority y años** - "5+ years", "senior", "lead".
|
|
18
|
+
5. **Soft skills explícitos** - communication, ownership, cross-functional.
|
|
19
|
+
6. **Señales de cultura / frases gatillo** - ej. "code-forward", "startup mentality", "high autonomy". Suelen indicar qué valoran y dan ángulo para el summary y la cover letter.
|
|
20
20
|
|
|
21
21
|
## Mapeo contra el perfil
|
|
22
22
|
|
|
@@ -24,7 +24,7 @@ Los Applicant Tracking Systems (Greenhouse, Lever, Workday, Workable, etc.) hace
|
|
|
24
24
|
|---|---|---|---|
|
|
25
25
|
| React.js | Sí | "Built React + TS frontends @ X" | resaltar arriba |
|
|
26
26
|
| Kubernetes | Parcial | exposición en CI/CD | mencionar honesto |
|
|
27
|
-
| Go | No |
|
|
27
|
+
| Go | No | - | gap; no inventar |
|
|
28
28
|
|
|
29
29
|
- **Must-have que tenés** → arriba, con espacio, con la palabra exacta.
|
|
30
30
|
- **Must-have parcial** → mencionar con honestidad ("exposure to…").
|
|
@@ -41,6 +41,6 @@ Los Applicant Tracking Systems (Greenhouse, Lever, Workday, Workable, etc.) hace
|
|
|
41
41
|
- [ ] Una sola columna, sin tablas/text boxes.
|
|
42
42
|
- [ ] Headers de sección estándar (Experience, Skills, Education…).
|
|
43
43
|
- [ ] Fechas consistentes MM/YYYY.
|
|
44
|
-
- [ ] Texto seleccionable (no imagen)
|
|
44
|
+
- [ ] Texto seleccionable (no imagen) - el export de `/cv-ats-export` ya lo garantiza.
|
|
45
45
|
- [ ] Nombre del archivo profesional (`Nombre_Apellido_Empresa.pdf`).
|
|
46
46
|
- [ ] Contacto en el cuerpo, no en el header/footer del documento.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hub-note
|
|
3
|
+
description: "Crea o actualiza un hub file (MOC) del vault: una nota por entidad que importa (persona, herramienta, concepto, empresa) que acumula conocimiento y conecta PARA con Zettelkasten. Triggers: hub file, MOC, mapa de contenido, nota de entidad, crear hub de, actualizar hub, nota de persona."
|
|
4
|
+
argument-hint: "[entidad] [--update]"
|
|
5
|
+
category: "pkm"
|
|
6
|
+
user-invocable: true
|
|
7
|
+
allowed-tools: Read, Glob, Grep, Write, Edit
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Hub Note - Tejido conectivo del vault
|
|
11
|
+
|
|
12
|
+
Un hub file es una nota por entidad que importa. No contiene conocimiento propio: contiene **el estado actual** de esa entidad y **los links** a todo lo que se sabe de ella. Es lo que hace que PARA (carpetas) y Zettelkasten (notas planas) convivan sin pelearse.
|
|
13
|
+
|
|
14
|
+
Entidad: `$ARGUMENTS`
|
|
15
|
+
|
|
16
|
+
Aplica la rule `vault-conventions`.
|
|
17
|
+
|
|
18
|
+
**Rutas por rol:** los destinos se nombran por rol y la ruta real de cada uno sale del `## Rutas` del `CLAUDE.md` del vault (leelo antes de escribir). Los defaults entre paréntesis solo aplican si el vault no declara otra cosa.
|
|
19
|
+
|
|
20
|
+
## Fase 1 - Decidir si la entidad merece hub
|
|
21
|
+
|
|
22
|
+
El criterio es la recurrencia, no la importancia: **la entidad apareció en tres dumps o notas distintas**. Antes de eso es una mención, y un hub por mención produce cientos de notas de una línea que nadie visita.
|
|
23
|
+
|
|
24
|
+
1. Buscar la entidad con `/vault-recall` si está disponible, o `Grep` en los roles `inbox`, `daily` y `atomic` (defaults `_inbox/`, `Reflect/Daily/`, `03_Resources/`) por el nombre y sus variantes.
|
|
25
|
+
2. Contar apariciones y reportarlas con los links.
|
|
26
|
+
3. Si hay menos de tres, decirlo y proponer esperar. Si el usuario quiere el hub igual (una persona nueva en el equipo, un proyecto que arranca), se crea: la anticipación es un motivo válido, la duda no.
|
|
27
|
+
|
|
28
|
+
Verdict: PASS si hay tres apariciones o una razón explícita del usuario.
|
|
29
|
+
|
|
30
|
+
## Fase 2 - Buscar el hub existente
|
|
31
|
+
|
|
32
|
+
`Glob` en `<hubs>` (default `Hubs/`) y revisar los `aliases` del frontmatter de los hubs que haya. Las entidades llegan con nombres distintos ("Educabot", "educabot", "EB"): si ya existe un hub para la entidad bajo otro nombre, **actualizar ese** y agregar el nombre nuevo a `aliases`. Nunca crear un segundo hub para la misma entidad: es el duplicado más caro del vault, porque parte el conocimiento en dos lugares que nadie reconcilia.
|
|
33
|
+
|
|
34
|
+
## Fase 3 - Escribir
|
|
35
|
+
|
|
36
|
+
Con approval, crear o actualizar el hub en `<hubs>` (default `Hubs/`) desde `<templates>/Hub.md`.
|
|
37
|
+
|
|
38
|
+
Al **crear**:
|
|
39
|
+
- Título: el nombre canónico de la entidad. Las variantes van a `aliases`.
|
|
40
|
+
- Una o dos líneas de qué es y por qué tiene nota propia.
|
|
41
|
+
- `## Estado actual`: lo que hay que saber hoy.
|
|
42
|
+
- `## Notas`: links a las notas atómicas y proyectos del tema que ya existan (los que encontraste en la fase 1).
|
|
43
|
+
- `## Historial`: una línea por aparición relevante, formato `- YYYY-MM-DD - qué pasó`, lo más nuevo arriba.
|
|
44
|
+
- `status`: `seed` al crearlo, `provisional` cuando ya acumuló contenido. Un hub que el usuario mantiene al día puede quedar `evergreen`, pero lo marca él.
|
|
45
|
+
- `repos:` si la entidad tiene código (una herramienta propia, un proyecto, un servicio). Es el puente al repo, y se traduce a path local en `codebases.md` del vault. **No copies arquitectura al hub:** el hub dice qué es y por qué, el repo dice cómo está hecho, y el que copia se desactualiza.
|
|
46
|
+
|
|
47
|
+
Al **actualizar** (`--update`, o cuando el hub ya existe):
|
|
48
|
+
- Agregar la entrada nueva al `## Historial`, sin duplicar una que ya esté con la misma fecha y el mismo contenido.
|
|
49
|
+
- **`## Estado actual` se reescribe, no se acumula.** Es la sección que responde "qué sé hoy de esto"; si se convierte en un log, el hub deja de servir para lo único que sirve. Lo que se reemplaza y sigue siendo relevante baja al historial.
|
|
50
|
+
- `## Notas`: agregar los links nuevos.
|
|
51
|
+
|
|
52
|
+
## Fase 4 - Conectar
|
|
53
|
+
|
|
54
|
+
- El hub linkea hacia las notas atómicas y los proyectos. Los dumps y dailies linkean **hacia** el hub. El hub no linkea a dumps ni a dailies: son registro, no conocimiento, y llenan el hub de ruido en un mes.
|
|
55
|
+
- Si el hub cubre un tema amplio y ya pasó las 30 o 40 entradas en `## Notas`, proponer partirlo en sub-hubs por subtema. Un hub que nadie puede leer de arriba a abajo dejó de ser un mapa.
|
|
56
|
+
|
|
57
|
+
Hub COMPLETE cuando tiene estado actual, al menos un link saliente, y las apariciones encontradas quedaron en el historial.
|
|
58
|
+
|
|
59
|
+
## Reglas
|
|
60
|
+
|
|
61
|
+
- Un hub por entidad. Los alias van al frontmatter, no a un hub nuevo.
|
|
62
|
+
- El hub no acumula conocimiento propio: si querés explicar una idea, es una nota atómica (`/zettel`) linkeada desde acá.
|
|
63
|
+
- Nunca borrar entradas del historial: si algo dejó de ser cierto, se agrega la entrada nueva.
|
|
64
|
+
- Sin guiones largos.
|
|
65
|
+
|
|
66
|
+
## Handoff
|
|
67
|
+
|
|
68
|
+
Con el hub listo, el siguiente paso es `/zettel` para las ideas del tema que todavía no tienen nota propia, o volver a `/review-dump` si esto salió procesando el día. `/vault-audit` va a usar los hubs para distinguir una huérfana real de una nota que simplemente todavía no fue linkeada.
|
|
@@ -7,14 +7,14 @@ user-invocable: true
|
|
|
7
7
|
allowed-tools: Read, Glob, Grep, Write, Edit, WebFetch
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
# Interview Prep
|
|
10
|
+
# Interview Prep - Preparación de entrevista
|
|
11
11
|
|
|
12
12
|
Preparás al usuario para una entrevista concreta: research de la empresa, banco de preguntas probable según rol y ronda, respuestas **STAR** construidas desde su experiencia real, preguntas inteligentes para hacer, y red flags a detectar. El output queda en una nota de `06-Entrevistas/`.
|
|
13
13
|
|
|
14
14
|
## Inputs
|
|
15
15
|
|
|
16
16
|
- **Aplicación / empresa / rol** (`03-Aplicaciones/`, `04-Empresas/`) y la **ronda** (recruiter screen, técnica, system design, hiring manager, cultural, final).
|
|
17
|
-
- **Perfil maestro** (`01-Perfiles/`)
|
|
17
|
+
- **Perfil maestro** (`01-Perfiles/`) - de ahí salen las historias para las respuestas STAR.
|
|
18
18
|
- **Entrevistadores** si se conocen (research de background ayuda).
|
|
19
19
|
|
|
20
20
|
## Qué producís
|
|
@@ -28,19 +28,19 @@ Preparás al usuario para una entrevista concreta: research de la empresa, banco
|
|
|
28
28
|
|
|
29
29
|
### 2. Banco de preguntas por ronda
|
|
30
30
|
- **Recruiter screen:** motivación, expectativas salariales, disponibilidad, "contame de vos".
|
|
31
|
-
- **Técnica:** según stack del JD
|
|
31
|
+
- **Técnica:** según stack del JD - fundamentos, problemas, debugging, code review.
|
|
32
32
|
- **System design** (si aplica): patrones, trade-offs, escala.
|
|
33
33
|
- **Hiring manager / comportamiento:** liderazgo, conflicto, fracaso, impacto.
|
|
34
34
|
- **Cultural:** valores, formas de trabajo, por qué esta empresa.
|
|
35
|
-
- Marcar las **3
|
|
35
|
+
- Marcar las **3-5 más probables** para este rol específico.
|
|
36
36
|
|
|
37
37
|
### 3. Respuestas STAR
|
|
38
38
|
- Construir respuestas con el método **STAR** (Situación, Tarea, Acción, Resultado) usando logros reales del perfil maestro.
|
|
39
|
-
- Cada respuesta: concreta, con métrica, 60
|
|
39
|
+
- Cada respuesta: concreta, con métrica, 60-90 segundos hablada.
|
|
40
40
|
- Ver `references/star-framework.md`.
|
|
41
41
|
|
|
42
42
|
### 4. Preguntas para hacer
|
|
43
|
-
- 5
|
|
43
|
+
- 5-7 preguntas inteligentes que demuestran research y filtran si la empresa te conviene (equipo, expectativas de los primeros 90 días, cómo miden éxito, deuda técnica, proceso).
|
|
44
44
|
|
|
45
45
|
### 5. Red flags a detectar
|
|
46
46
|
- Señales de mala empresa/equipo durante la entrevista (proceso caótico, evasión sobre cultura/turnover, expectativas irreales, falta de claridad de rol, hostilidad).
|
|
@@ -56,7 +56,7 @@ Preparás al usuario para una entrevista concreta: research de la empresa, banco
|
|
|
56
56
|
|
|
57
57
|
1. Leer aplicación + empresa + perfil. WebFetch del sitio/notas de la empresa.
|
|
58
58
|
2. Crear nota en `06-Entrevistas/` con el template `Entrevista`.
|
|
59
|
-
3. Llenar research, banco de preguntas (marcando las top), STAR de las 3
|
|
59
|
+
3. Llenar research, banco de preguntas (marcando las top), STAR de las 3-5 historias clave, preguntas a hacer, red flags.
|
|
60
60
|
4. Ofrecer un **mock**: vos hacés de entrevistador y das feedback sobre las respuestas.
|
|
61
61
|
5. Post-entrevista: ayudar a registrar feedback y definir próximo paso / follow-up (con `/cold-outreach`).
|
|
62
62
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
# STAR Framework
|
|
1
|
+
# STAR Framework - Respuestas de comportamiento
|
|
2
2
|
|
|
3
3
|
STAR estructura respuestas a preguntas de comportamiento ("contame de una vez que…") para que sean concretas, completas y memorables. La mayoría de los candidatos divaga; STAR te da una historia con resultado.
|
|
4
4
|
|
|
5
5
|
## Las 4 partes
|
|
6
6
|
|
|
7
|
-
- **S
|
|
8
|
-
- **T
|
|
9
|
-
- **A
|
|
10
|
-
- **R
|
|
7
|
+
- **S - Situación:** el contexto, breve. Dónde, cuándo, qué estaba pasando. (1-2 oraciones)
|
|
8
|
+
- **T - Tarea:** tu responsabilidad / el problema a resolver. (1 oración)
|
|
9
|
+
- **A - Acción:** qué hiciste *vos* (no "el equipo"). El grueso de la respuesta. Decisiones concretas. (2-4 oraciones)
|
|
10
|
+
- **R - Resultado:** el impacto, **con número** siempre que se pueda. Qué aprendiste. (1-2 oraciones)
|
|
11
11
|
|
|
12
|
-
Objetivo: 60
|
|
12
|
+
Objetivo: 60-90 segundos hablado. Ni telegrama, ni monólogo de 5 minutos.
|
|
13
13
|
|
|
14
14
|
## Ejemplo
|
|
15
15
|
|
|
@@ -20,9 +20,9 @@ Objetivo: 60–90 segundos hablado. Ni telegrama, ni monólogo de 5 minutos.
|
|
|
20
20
|
> **A:** Perfilé el hot path, encontré queries N+1 y serialización redundante; introduje caching por sesión y batch de writes, y agregué métricas para validar.
|
|
21
21
|
> **R:** Latencia -25% y estabilidad del server +40%; duplicamos jugadores concurrentes sin sumar costos. Aprendí a medir antes de optimizar.
|
|
22
22
|
|
|
23
|
-
## Banco de historias (preparar 5
|
|
23
|
+
## Banco de historias (preparar 5-6)
|
|
24
24
|
|
|
25
|
-
Construí 5
|
|
25
|
+
Construí 5-6 historias STAR reutilizables desde el perfil maestro, cubriendo:
|
|
26
26
|
|
|
27
27
|
1. **Logro/impacto** del que estés orgulloso (con métrica).
|
|
28
28
|
2. **Problema técnico difícil** que resolviste.
|
|
@@ -31,11 +31,11 @@ Construí 5–6 historias STAR reutilizables desde el perfil maestro, cubriendo:
|
|
|
31
31
|
5. **Liderazgo / iniciativa** (lideraste algo, mentoreaste, empujaste un cambio).
|
|
32
32
|
6. **Ambigüedad / cambio de prioridades** que manejaste.
|
|
33
33
|
|
|
34
|
-
La misma historia puede servir para varias preguntas
|
|
34
|
+
La misma historia puede servir para varias preguntas - lo que cambia es qué parte enfatizás.
|
|
35
35
|
|
|
36
36
|
## Errores comunes
|
|
37
37
|
|
|
38
|
-
- Quedarse en "nosotros"
|
|
38
|
+
- Quedarse en "nosotros" - la entrevista evalúa *tu* aporte. Decí "yo".
|
|
39
39
|
- Saltearse el Resultado, o un resultado sin número.
|
|
40
40
|
- Demasiada Situación, poca Acción.
|
|
41
41
|
- Historias vagas/inventadas que no aguantan repreguntas.
|