claude-code-arcane 2.2.0 → 2.4.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.
Files changed (144) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +104 -55
  3. package/agents/career/career-strategist.md +88 -0
  4. package/agents/career/cv-reviewer.md +81 -0
  5. package/agents/career/hiring-manager.md +68 -0
  6. package/agents/career/mock-interviewer.md +76 -0
  7. package/agents/freelance/client-screener.md +84 -0
  8. package/agents/freelance/discovery-call.md +65 -0
  9. package/agents/freelance/pipeline-strategist.md +99 -0
  10. package/agents/freelance/proposal-reviewer.md +82 -0
  11. package/agents/game/ue-blueprint-specialist.md +125 -0
  12. package/agents/game/ue-gas-specialist.md +133 -0
  13. package/agents/game/ue-umg-specialist.md +131 -0
  14. package/dist/cli.js +57 -13
  15. package/docs/RELEASE-SETUP.md +1 -1
  16. package/docs/SKILLS-CATALOG.md +67 -4
  17. package/docs/USER-GUIDE.md +77 -72
  18. package/docs/agent-hierarchy.md +21 -1
  19. package/docs/presentations/build_arcane_deck.py +2 -2
  20. package/docs/presentations/build_arcane_deck_12.py +2 -2
  21. package/hooks/detect-unreal.sh +90 -0
  22. package/package.json +2 -2
  23. package/profiles/freelance.yaml +43 -0
  24. package/profiles/job-hunt.yaml +5 -2
  25. package/profiles/unreal-dev.yaml +97 -0
  26. package/rules/drafter-reviewer.md +16 -3
  27. package/rules/freelance-guardrails.md +53 -0
  28. package/rules/gamedev/unreal-code.md +125 -0
  29. package/skills/career-registry/SKILL.md +95 -0
  30. package/skills/career-registry/scripts/career_registry.py +488 -0
  31. package/skills/client-screen/SKILL.md +83 -0
  32. package/skills/client-screen/references/red-flags.md +95 -0
  33. package/skills/cover-letter/SKILL.md +4 -3
  34. package/skills/cv-tailor/SKILL.md +11 -2
  35. package/skills/freelance-deliver/SKILL.md +90 -0
  36. package/skills/freelance-hunt/SKILL.md +126 -0
  37. package/skills/freelance-hunt/references/templates/Connects.md +39 -0
  38. package/skills/freelance-hunt/references/templates/Contrato.md +60 -0
  39. package/skills/freelance-hunt/references/templates/Propuesta.md +66 -0
  40. package/skills/freelance-kickoff/SKILL.md +94 -0
  41. package/skills/freelance-pipeline/SKILL.md +109 -0
  42. package/skills/freelance-pipeline/scripts/import_history.py +425 -0
  43. package/skills/freelance-profile/SKILL.md +93 -0
  44. package/skills/freelance-proposal/SKILL.md +112 -0
  45. package/skills/freelance-scan/SKILL.md +196 -0
  46. package/skills/freelance-scan/references/dedup.md +35 -0
  47. package/skills/freelance-scan/references/platforms.md +167 -0
  48. package/skills/freelance-scan/scripts/freelance_search.py +1077 -0
  49. package/skills/install-mcp/SKILL.md +135 -46
  50. package/skills/install-mcp/references/unreal-operations.md +55 -0
  51. package/skills/interview-prep/SKILL.md +11 -3
  52. package/skills/job-aplicar/SKILL.md +5 -1
  53. package/skills/job-hunt/SKILL.md +17 -0
  54. package/skills/job-outcome/SKILL.md +15 -1
  55. package/skills/job-upskill/SKILL.md +10 -2
  56. package/skills/ue-actor-component-architecture/SKILL.md +509 -0
  57. package/skills/ue-actor-component-architecture/references/actor-lifecycle.md +301 -0
  58. package/skills/ue-actor-component-architecture/references/component-types.md +592 -0
  59. package/skills/ue-ai-navigation/SKILL.md +526 -0
  60. package/skills/ue-ai-navigation/references/behavior-tree-patterns.md +392 -0
  61. package/skills/ue-ai-navigation/references/behavior-tree-workflow.md +107 -0
  62. package/skills/ue-ai-navigation/references/custom-bttask.md +104 -0
  63. package/skills/ue-ai-navigation/references/eqs-reference.md +423 -0
  64. package/skills/ue-animation-system/SKILL.md +521 -0
  65. package/skills/ue-animation-system/references/anim-notify-reference.md +486 -0
  66. package/skills/ue-animation-system/references/locomotion-setup.md +550 -0
  67. package/skills/ue-async-threading/SKILL.md +433 -0
  68. package/skills/ue-async-threading/references/thread-safety-guide.md +213 -0
  69. package/skills/ue-async-threading/references/threading-patterns.md +345 -0
  70. package/skills/ue-audio-system/SKILL.md +527 -0
  71. package/skills/ue-audio-system/references/audio-setup-patterns.md +700 -0
  72. package/skills/ue-blueprints/SKILL.md +134 -0
  73. package/skills/ue-blueprints/references/communication.md +82 -0
  74. package/skills/ue-character-movement/SKILL.md +475 -0
  75. package/skills/ue-character-movement/references/cmc-extension-patterns.md +335 -0
  76. package/skills/ue-character-movement/references/movement-pipeline.md +189 -0
  77. package/skills/ue-cpp-foundations/SKILL.md +533 -0
  78. package/skills/ue-cpp-foundations/references/components-and-gc.md +107 -0
  79. package/skills/ue-cpp-foundations/references/container-patterns.md +544 -0
  80. package/skills/ue-cpp-foundations/references/delegate-patterns.md +497 -0
  81. package/skills/ue-cpp-foundations/references/gameplay-classes-cpp.md +136 -0
  82. package/skills/ue-cpp-foundations/references/property-specifiers.md +306 -0
  83. package/skills/ue-data-assets-tables/SKILL.md +527 -0
  84. package/skills/ue-data-assets-tables/references/asset-loading-patterns.md +306 -0
  85. package/skills/ue-data-assets-tables/references/data-driven-design.md +378 -0
  86. package/skills/ue-editor-tools/SKILL.md +523 -0
  87. package/skills/ue-editor-tools/references/detail-customization-patterns.md +395 -0
  88. package/skills/ue-editor-tools/references/editor-module-setup.md +480 -0
  89. package/skills/ue-game-features/SKILL.md +477 -0
  90. package/skills/ue-game-features/references/experience-system.md +222 -0
  91. package/skills/ue-game-features/references/game-feature-patterns.md +308 -0
  92. package/skills/ue-gameplay-abilities/SKILL.md +518 -0
  93. package/skills/ue-gameplay-abilities/references/ability-task-reference.md +391 -0
  94. package/skills/ue-gameplay-abilities/references/gameplay-effect-reference.md +397 -0
  95. package/skills/ue-gameplay-abilities/references/gas-setup-patterns.md +369 -0
  96. package/skills/ue-gameplay-framework/SKILL.md +466 -0
  97. package/skills/ue-gameplay-framework/references/framework-class-map.md +243 -0
  98. package/skills/ue-input-system/SKILL.md +394 -0
  99. package/skills/ue-input-system/references/cpp-setup.md +131 -0
  100. package/skills/ue-input-system/references/enhanced-input-workflow.md +117 -0
  101. package/skills/ue-input-system/references/input-action-reference.md +731 -0
  102. package/skills/ue-mass-entity/SKILL.md +476 -0
  103. package/skills/ue-mass-entity/references/mass-entity-patterns.md +319 -0
  104. package/skills/ue-mass-entity/references/mass-fragment-reference.md +119 -0
  105. package/skills/ue-materials-rendering/SKILL.md +526 -0
  106. package/skills/ue-materials-rendering/references/material-parameter-reference.md +216 -0
  107. package/skills/ue-materials-rendering/references/post-process-settings.md +383 -0
  108. package/skills/ue-module-build-system/SKILL.md +487 -0
  109. package/skills/ue-module-build-system/references/build-cs-reference.md +418 -0
  110. package/skills/ue-module-build-system/references/common-build-errors.md +381 -0
  111. package/skills/ue-naming-conventions/SKILL.md +142 -0
  112. package/skills/ue-naming-conventions/references/asset-name-modifiers.md +233 -0
  113. package/skills/ue-naming-conventions/references/content-structure.md +83 -0
  114. package/skills/ue-networking-replication/SKILL.md +452 -0
  115. package/skills/ue-networking-replication/references/replication-patterns.md +526 -0
  116. package/skills/ue-networking-replication/references/rpc-decision-guide.md +393 -0
  117. package/skills/ue-niagara-effects/SKILL.md +531 -0
  118. package/skills/ue-niagara-effects/references/niagara-data-interfaces.md +491 -0
  119. package/skills/ue-niagara-effects/references/niagara-parameter-types.md +153 -0
  120. package/skills/ue-niagara-effects/references/niagara-workflow.md +115 -0
  121. package/skills/ue-packaging/SKILL.md +116 -0
  122. package/skills/ue-physics-collision/SKILL.md +423 -0
  123. package/skills/ue-physics-collision/references/collision-channel-setup.md +218 -0
  124. package/skills/ue-physics-collision/references/trace-patterns.md +499 -0
  125. package/skills/ue-procedural-generation/SKILL.md +505 -0
  126. package/skills/ue-procedural-generation/references/pcg-node-reference.md +381 -0
  127. package/skills/ue-procedural-generation/references/procedural-mesh-patterns.md +940 -0
  128. package/skills/ue-project-context/SKILL.md +305 -0
  129. package/skills/ue-sequencer-cinematics/SKILL.md +506 -0
  130. package/skills/ue-sequencer-cinematics/references/sequencer-patterns.md +629 -0
  131. package/skills/ue-serialization-savegames/SKILL.md +524 -0
  132. package/skills/ue-serialization-savegames/references/save-system-architecture.md +705 -0
  133. package/skills/ue-state-trees/SKILL.md +489 -0
  134. package/skills/ue-state-trees/references/state-tree-mass-integration.md +184 -0
  135. package/skills/ue-state-trees/references/state-tree-patterns.md +321 -0
  136. package/skills/ue-testing-debugging/SKILL.md +520 -0
  137. package/skills/ue-testing-debugging/references/automation-test-patterns.md +387 -0
  138. package/skills/ue-testing-debugging/references/profiling-commands.md +357 -0
  139. package/skills/ue-ui-umg-slate/SKILL.md +431 -0
  140. package/skills/ue-ui-umg-slate/references/common-ui-setup.md +484 -0
  141. package/skills/ue-ui-umg-slate/references/widget-types.md +487 -0
  142. package/skills/ue-world-level-streaming/SKILL.md +518 -0
  143. package/skills/ue-world-level-streaming/references/streaming-patterns.md +414 -0
  144. package/templates/gamedev/unreal-project-context.md +107 -0
@@ -0,0 +1,97 @@
1
+ name: unreal-dev
2
+ description: "Programador Unreal Engine 5 — C++, Blueprints, GAS, replication, rendering, naming conventions, build y editor MCP"
3
+ type: base
4
+
5
+ skills:
6
+ # Foundation — read this first, every other ue-* skill depends on it
7
+ - ue-project-context
8
+ - ue-naming-conventions
9
+ # C++ & architecture
10
+ - ue-cpp-foundations
11
+ - ue-actor-component-architecture
12
+ - ue-gameplay-framework
13
+ - ue-module-build-system
14
+ - ue-async-threading
15
+ # Blueprints
16
+ - ue-blueprints
17
+ # Gameplay systems
18
+ - ue-gameplay-abilities
19
+ - ue-character-movement
20
+ - ue-animation-system
21
+ - ue-physics-collision
22
+ - ue-game-features
23
+ - ue-networking-replication
24
+ # AI & behaviour
25
+ - ue-ai-navigation
26
+ - ue-state-trees
27
+ - ue-mass-entity
28
+ # Rendering & VFX
29
+ - ue-materials-rendering
30
+ - ue-niagara-effects
31
+ # Audio & cinematics
32
+ - ue-audio-system
33
+ - ue-sequencer-cinematics
34
+ # World & data
35
+ - ue-world-level-streaming
36
+ - ue-procedural-generation
37
+ - ue-data-assets-tables
38
+ - ue-serialization-savegames
39
+ # UI & input
40
+ - ue-ui-umg-slate
41
+ - ue-input-system
42
+ # Tooling, build & QA
43
+ - ue-editor-tools
44
+ - ue-testing-debugging
45
+ - ue-packaging
46
+ # Cross-engine, reused from the shared library
47
+ # Unreal ships its own MCP as engine plugins; install-mcp only enables and connects it.
48
+ - install-mcp
49
+ - test-setup
50
+ - perf-profile
51
+ - optimize
52
+ - deps-audit
53
+ - env-sync
54
+ - security-audit
55
+ - release-checklist
56
+ - patch-notes
57
+ - onboard
58
+ - map-systems
59
+ - game-audit
60
+ - audit-game
61
+ - asset-audit
62
+ - accessibility
63
+ - balance-check
64
+ - consistency-check
65
+ - doc-gdd
66
+ - playtest-report
67
+
68
+ rules:
69
+ universal:
70
+ []
71
+ gamedev:
72
+ - unreal-code
73
+ - gameplay-code
74
+ - engine-code
75
+ - shader-code
76
+ - network-code
77
+ - ui-code
78
+ - ai-code
79
+
80
+ agents:
81
+ - game
82
+
83
+ permissions:
84
+ allow:
85
+ - "Bash(*RunUAT*)"
86
+ - "Bash(*UnrealBuildTool*)"
87
+ - "Bash(*UnrealEditor-Cmd*)"
88
+ - "Bash(*GenerateProjectFiles*)"
89
+ - "Glob(Source/**)"
90
+ - "Glob(Plugins/**)"
91
+ - "Grep(Source/**)"
92
+ deny:
93
+ - "Write(Content/**)"
94
+ - "Edit(Content/**)"
95
+ - "Write(Binaries/**)"
96
+ - "Write(Intermediate/**)"
97
+ - "Write(DerivedDataCache/**)"
@@ -9,14 +9,19 @@ Las rutas son relativas al career workspace (`./career-workspace/` o env `CAREER
9
9
  - Al terminar el borrador de un CV custom (flujo cv-tailor) o de una cover / mensaje de aplicación (flujo cover-letter) destinado a una postulación concreta.
10
10
  - NO aplica a ediciones menores de un CV ya revisado (typos, cambiar una fecha) ni a los CVs base de `02-CVs/` fuera de una postulación.
11
11
 
12
+ Quién la ejecuta: `/job-aplicar` (paso 7, obligatorio), y `/cv-tailor` y `/cover-letter` cuando se corren sueltos. Los tres declaran `Task` en `allowed-tools` justamente para poder cumplirla - un skill sin `Task` no puede aplicar esta regla, y ahí la regla sería solo una intención.
13
+
12
14
  ## El paso reviewer
13
15
 
14
- Lanzar UN agente `general-purpose` de contexto fresco vía el Agent tool, con este contenido inline en el prompt (para que no dependa de leer archivos de la conversación):
16
+ Lanzar UN agente **`cv-reviewer`** de contexto fresco vía el Agent tool. El agente ya trae la persona, el límite de lectura y el contrato de salida; el prompt solo tiene que aportar lo que el agente no puede saber:
15
17
 
16
18
  1. El texto completo de la job description.
17
19
  2. El borrador del CV y/o cover, verbatim.
18
- 3. Instrucción de lectura acotada: solo puede leer `01-Perfiles/<perfil usado>.md` del workspace. NO debe leer los templates ni el resto del workspace - critica contenido, no estructura.
19
- 4. Instrucción de research: búsqueda web breve sobre la empresa (misión, producto, noticias recientes, cultura) para detectar ángulos no aprovechados.
20
+ 3. Cuál es el perfil usado, para que sepa qué archivo de `01-Perfiles/` puede leer.
21
+
22
+ Va inline en el prompt para que no dependa de leer archivos de la conversación.
23
+
24
+ Si el agente `cv-reviewer` no está instalado (perfil `+job-hunt` sin su directorio de agentes), usar un `general-purpose` y pasarle en el prompt las cuatro restricciones: lectura acotada a `01-Perfiles/<perfil usado>.md`, prohibido leer templates y el resto del workspace, research web breve de la empresa, y el contrato de salida de abajo.
20
25
 
21
26
  El reviewer devuelve dos partes:
22
27
 
@@ -27,6 +32,14 @@ El reviewer devuelve dos partes:
27
32
  - Bullets que se pueden reformular como logro medible
28
33
  - Tono / estilo (registro, longitud, muletillas)
29
34
 
35
+ ## Segunda lente (opcional): `hiring-manager`
36
+
37
+ `cv-reviewer` contesta "¿pasa el filtro?". Un CV puede pasar con match del 85% y morir igual en el escritorio de quien contrata, por una razón distinta: **no hay evidencia de que la persona ya hizo el trabajo**.
38
+
39
+ Cuándo vale el segundo agente: postulación que importa, rol senior, o racha de rechazos post-CV. Se lanza **en paralelo** con `cv-reviewer` (no en cadena: son lentes independientes y encadenarlos solo suma latencia). Devuelve veredicto, evidencia faltante y las 3 preguntas que haría, que además son material de `/interview-prep`.
40
+
41
+ No es obligatorio. Para una aplicación de rutina, `cv-reviewer` solo alcanza.
42
+
30
43
  ## Reglas de aplicación del feedback
31
44
 
32
45
  - **Una sola ronda.** El drafter aplica la Parte A, incorpora de la Parte B lo que corresponda, y sigue. Sin ida y vuelta iterativo.
@@ -0,0 +1,53 @@
1
+ # Freelance Guardrails (marketplaces y clientes directos)
2
+
3
+ Buscar empleo es gratis: aplicás a 40 puestos y solo perdés tiempo. Freelancear no. Cada propuesta cuesta algo, cada contrato malo toca tu reputación, y cada "¿me agregás esto rapidito?" sin cobrar sale de tu bolsillo.
4
+
5
+ Estas cuatro reglas existen porque los tres recursos que se gastan (plata, reputación, tiempo no facturado) no se recuperan.
6
+
7
+ **El costo de postularse tiene nombre distinto en cada plataforma** y las reglas valen igual: Connects en Upwork, bids en Freelancer.com, y en outreach directo son las horas que ponés en escribir la propuesta. Donde abajo diga Connects, leé "lo que te cuesta postularte".
8
+
9
+ Las rutas son relativas al career workspace (`./career-workspace/` o env `CAREER_WORKSPACE`).
10
+
11
+ ## 1. Postularse cuesta plata: no se gasta sin screen
12
+
13
+ Nunca redactar una propuesta para una oferta cuyo cliente no pasó `/client-screen`, ni para una que quedó bajo el umbral de score.
14
+
15
+ Si el usuario quiere postularse igual a una que falló el screen, se puede - **pero se le dice qué falló y se registra en la nota**. Un pago sin verificar que nadie nombró es una postulación tirada, y peor: es la propuesta que sí te contestan y termina en disputa.
16
+
17
+ ## 2. La reputación se protege rechazando
18
+
19
+ Ganar un contrato no siempre es bueno. Casi toda plataforma calcula un puntaje sobre contratos cerrados (en Upwork es el Job Success Score) donde un cliente insatisfecho pesa más que dos contentos, y con clientes directos el equivalente son las referencias que no vas a poder pedir. Un contrato con alcance difuso, presupuesto irrealista o cliente sin historial es **riesgo de reputación**, no una oportunidad.
20
+
21
+ Cuando el screen marca riesgo alto, la recomendación por defecto es no postularse. Decir "no" es una acción del pipeline, no una ausencia de acción.
22
+
23
+ ## 3. Nada se cotiza abajo del piso
24
+
25
+ Todo bid pasa por el piso declarado en `01-Perfiles/` (tarifa mínima aceptable). El piso es **neto**, después de la comisión de la plataforma: si se queda un 10%, un piso de 40 USD/h exige bidear 45. Con cliente directo la comisión es cero, pero el piso sigue siendo neto de impuestos y de las horas no facturables.
26
+
27
+ Si el usuario todavía no fijó un piso, `/freelance-scan market` da la mediana de lo que cobran otros con su perfil. Es un punto de partida, no el piso: el piso lo define su costo de vida, no el mercado.
28
+
29
+ Alcance nuevo, precio nuevo. Ninguna propuesta ni contrato se amplía sin cotizarlo: si el trabajo extra no entra en un change order con número, no entra.
30
+
31
+ ## 4. El envío siempre lo hace el usuario
32
+
33
+ Ninguna skill de este perfil envía una propuesta, acepta un contrato ni gasta el presupuesto de postulaciones. Se redacta, se revisa, se muestra, y el usuario copia y manda.
34
+
35
+ Esto no es prudencia nuestra: **la API de Upwork no tiene mutation para postularse ni para gastar Connects**, justamente para frenar bots de auto-bidding, y las demás plataformas prohíben el envío automatizado en sus términos. Ninguna skill debe pretender lo contrario, y una que lo intentara estaría violando los ToS además de esta regla.
36
+
37
+ El corolario para las **fuentes**: ninguna skill del perfil puede depender de credenciales que cada usuario tenga que conseguir por su cuenta. Este perfil lo instala cualquiera, y una fuente con API key aprobada a mano funciona para uno y está rota para el resto. Las fuentes automáticas son públicas y sin key (ver `skills/freelance-scan/references/platforms.md`); lo demás se pega a mano.
38
+
39
+ ## La estructura no la sostiene este archivo
40
+
41
+ Una regla sin columna derecha es una intención.
42
+
43
+ | Regla | Qué la hace cumplir |
44
+ |---|---|
45
+ | Screen antes de gastar en postularse | `/freelance-proposal` exige la nota de screen; sin ella, pregunta y no redacta |
46
+ | Rechazar por riesgo de reputación | `/client-screen` emite veredicto explícito; el agente `client-screener` es adversarial por diseño |
47
+ | Piso de tarifa | `/freelance-proposal` lee el piso del perfil y falla ruidoso si el bid queda abajo; `/freelance-scan market` da la referencia de mercado |
48
+ | Alcance nuevo, precio nuevo | `/freelance-pipeline` detecta drift de alcance en contratos activos y pide change order |
49
+ | Envío manual | Ningún script del perfil escribe a una plataforma: `freelance_search.py` solo lee, y no hay otro |
50
+
51
+ ## Registro
52
+
53
+ Toda decisión de no postularse se registra igual que una postulación: nota en `03-Aplicaciones/` con `estado: descartado` y el motivo en `## Notas`. Los descartes son la mitad de los datos que `/freelance-pipeline` necesita para decirte si tu criterio de selección funciona.
@@ -0,0 +1,125 @@
1
+ ---
2
+ paths:
3
+ - "Source/**"
4
+ - "Plugins/**/Source/**"
5
+ ---
6
+
7
+ # Unreal Engine C++ Rules
8
+
9
+ - Every UObject reference held by another UObject must be a `TObjectPtr<>` marked `UPROPERTY()` — an unmarked pointer is invisible to the GC and becomes a dangling pointer
10
+ - Never `new`/`delete` a UObject — use `NewObject<>()` or `CreateDefaultSubobject<>()`; use `TSharedPtr`/`TUniquePtr`/`TWeakPtr` only for non-UObject types
11
+ - Follow engine naming: `U` for UObject, `A` for AActor, `F` for structs, `E` for enums, `I` for interfaces, `T` for templates
12
+ - Restrict every identifier to `[A-Za-z0-9_]` — no whitespace, no symbols, no Unicode. This applies to type names, asset references and paths alike; non-ASCII identifiers break cooking, batch tools and source control in ways that surface far from the cause
13
+ - Use `FName` for identifiers and lookups, `FText` for anything shown to a player, `FString` only for manipulation — never build display strings by concatenating `FString` for localized UI
14
+ - Use `TArray`/`TMap`/`TSet`, not STL containers, in any reflected or engine-facing code
15
+ - `Tick` is opt-in, not default: disable it (`PrimaryActorTick.bCanEverTick = false`) and use timers, delegates or events instead. Ticking work multiplied across instances is a measured cost, not an assumption
16
+ - ZERO allocations in hot paths (tick, animation, physics, rendering) — pre-allocate, pool and reuse
17
+ - Always call `Super::` in overridden engine functions (`BeginPlay`, `EndPlay`, `Tick`, `GetLifetimeReplicatedProps`, `PostInitializeComponents`)
18
+ - Every replicated `UPROPERTY(Replicated)` must appear in `GetLifetimeReplicatedProps` with a `DOREPLIFETIME` entry, and every Server RPC must validate its input — never trust the client
19
+ - Use soft references (`TSoftObjectPtr`, `TSoftClassPtr`) plus the Asset Manager for assets that are not always needed; a hard reference pulls the whole asset tree into memory
20
+ - No synchronous load of large assets on the game thread during gameplay — use `StreamableManager` / async loading
21
+ - UObject access happens on the game thread only; async completion paths must handle their owner being destroyed mid-flight
22
+ - Editor-only code lives in an editor module or behind `WITH_EDITOR`, and never ships in a runtime target
23
+ - Profile with Unreal Insights and `stat` commands before AND after every optimization — document the measured numbers
24
+ - Blueprint Nativization was removed in UE5; never propose it as an optimization
25
+
26
+ ## Examples
27
+
28
+ **Correct** (GC-visible reference, no tick, validated RPC):
29
+
30
+ ```cpp
31
+ UCLASS()
32
+ class AGate : public AActor
33
+ {
34
+ GENERATED_BODY()
35
+
36
+ public:
37
+ AGate()
38
+ {
39
+ PrimaryActorTick.bCanEverTick = false; // event-driven, nothing to tick
40
+ }
41
+
42
+ protected:
43
+ virtual void BeginPlay() override
44
+ {
45
+ Super::BeginPlay(); // never skip Super
46
+ OnActorBeginOverlap.AddDynamic(this, &AGate::HandleOverlap);
47
+ }
48
+
49
+ UFUNCTION(Server, Reliable, WithValidation)
50
+ void ServerRequestOpen();
51
+
52
+ private:
53
+ // TObjectPtr + UPROPERTY: the GC can see and keep this alive.
54
+ UPROPERTY(VisibleAnywhere)
55
+ TObjectPtr<UStaticMeshComponent> Frame;
56
+
57
+ // Soft reference: the VFX only loads when the gate actually opens.
58
+ UPROPERTY(EditDefaultsOnly)
59
+ TSoftObjectPtr<UNiagaraSystem> OpenEffect;
60
+ };
61
+
62
+ bool AGate::ServerRequestOpen_Validate()
63
+ {
64
+ return true;
65
+ }
66
+
67
+ void AGate::ServerRequestOpen_Implementation()
68
+ {
69
+ // Server re-checks authority and state; the client's word is not enough.
70
+ if (!HasAuthority() || bIsLocked)
71
+ {
72
+ return;
73
+ }
74
+ OpenInternal();
75
+ }
76
+ ```
77
+
78
+ **Incorrect** (invisible to GC, needless tick, trusted client, hot-path allocation):
79
+
80
+ ```cpp
81
+ UCLASS()
82
+ class AGate : public AActor
83
+ {
84
+ GENERATED_BODY()
85
+
86
+ // VIOLATION: raw pointer with no UPROPERTY — GC cannot see it, this will dangle
87
+ UStaticMeshComponent* Frame;
88
+
89
+ // VIOLATION: hard reference, loads the VFX and its dependencies with this actor
90
+ UPROPERTY()
91
+ UNiagaraSystem* OpenEffect;
92
+
93
+ virtual void BeginPlay() override
94
+ {
95
+ // VIOLATION: missing Super::BeginPlay()
96
+ Frame = new UStaticMeshComponent(); // VIOLATION: never new a UObject
97
+ }
98
+
99
+ virtual void Tick(float DeltaTime) override
100
+ {
101
+ // VIOLATION: allocates every frame
102
+ TArray<AActor*> Nearby;
103
+ UGameplayStatics::GetAllActorsOfClass(GetWorld(), APawn::StaticClass(), Nearby);
104
+
105
+ // VIOLATION: string comparison in a hot path — use FName or a tag
106
+ for (AActor* A : Nearby)
107
+ {
108
+ if (A->GetName() == TEXT("BP_Player_C_0"))
109
+ {
110
+ OpenInternal();
111
+ }
112
+ }
113
+ }
114
+
115
+ UFUNCTION(Server, Unreliable)
116
+ void ServerRequestOpen(bool bClientSaysUnlocked)
117
+ {
118
+ // VIOLATION: trusts a client-supplied authority decision
119
+ if (bClientSaysUnlocked)
120
+ {
121
+ OpenInternal();
122
+ }
123
+ }
124
+ };
125
+ ```
@@ -0,0 +1,95 @@
1
+ ---
2
+ name: career-registry
3
+ description: "Traceability across the whole career workspace: check whether you already applied somewhere before spending another application, export everything to CSV, and audit the registry for gaps and drift. Covers job applications, freelance proposals and contracts. Triggers: ya me postule a, ya aplique aca, exportar postulaciones a csv, registro de aplicaciones, trazabilidad, historial de postulaciones, cuantas mande, planilla de postulaciones, auditar el registro."
4
+ argument-hint: "[check <empresa|url> | export | stats | audit]"
5
+ category: "career"
6
+ user-invocable: true
7
+ allowed-tools: Read, Glob, Grep, Bash, Write, Edit
8
+ ---
9
+
10
+ # Career Registry - Trazabilidad y registro
11
+
12
+ Contestás la pregunta que grepear a mano contesta mal: **¿ya me postulé acá?** Y das el registro completo en CSV para mirarlo en una planilla.
13
+
14
+ Sirve a los dos perfiles: `+job-hunt` (empleo) y `+freelance` (proyectos). Rutas relativas al career workspace (`--workspace`, env `CAREER_WORKSPACE`, o `./career-workspace/`).
15
+
16
+ Modo: `$ARGUMENTS`
17
+
18
+ ## La regla que sostiene todo esto
19
+
20
+ **Las notas son la fuente de verdad. El CSV se deriva de ellas, siempre.**
21
+
22
+ No hay una segunda base que mantener sincronizada, y no la va a haber: una segunda base diverge en dos semanas y después nadie sabe cuál miente. Es el mismo flujo unidireccional que el dedup de `/job-scrape` (`seen_jobs` → nota → vista, nunca de vuelta).
23
+
24
+ Consecuencia práctica: si el CSV está mal, se arregla la nota, no el CSV. Y si el usuario pide "guardame el CSV para editarlo a mano", avisale que en la próxima corrida se pisa.
25
+
26
+ ## Los cuatro modos
27
+
28
+ ```bash
29
+ python .claude/skills/career-registry/scripts/career_registry.py check "Acme"
30
+ python .claude/skills/career-registry/scripts/career_registry.py check "https://www.linkedin.com/jobs/view/123"
31
+ python .claude/skills/career-registry/scripts/career_registry.py export --csv registro.csv
32
+ python .claude/skills/career-registry/scripts/career_registry.py stats
33
+ python .claude/skills/career-registry/scripts/career_registry.py audit
34
+ ```
35
+
36
+ ### `check` - antes de gastar otra postulación
37
+
38
+ Busca por **tres claves** porque el usuario pega cualquiera de las tres: nombre de la contraparte, URL de la oferta, o título de la nota.
39
+
40
+ Es tolerante donde importa: `acme` encuentra a "Acme Inc" (ignora sufijos legales), `tecnologia latam` encuentra a "Tecnología Latam SA" (ignora acentos), y una URL con `?utm_source=...` distinto encuentra la misma oferta (canoniza el link, igual que el dedup).
41
+
42
+ Devuelve un veredicto de tres valores, y la diferencia entre los dos primeros importa:
43
+
44
+ | Veredicto | Qué significa |
45
+ |---|---|
46
+ | `YA TE POSTULASTE` | Hay una nota en estado enviado. No repitas |
47
+ | `YA LO VISTE, NO TE POSTULASTE` | Hay nota o entrada de dedup, pero nunca se envió. Vale revisarla antes de descartarla de nuevo |
48
+ | `SIN REGISTRO` | Nunca apareció |
49
+
50
+ Cuándo correrlo: **antes de `/client-screen` o `/job-aplicar`**, cuando el nombre suena conocido. Un screen sobre algo que ya descartaste hace tres meses es trabajo repetido, y peor, te hace repetir el descarte sin recordar por qué.
51
+
52
+ ### `export` - el CSV
53
+
54
+ Una fila por nota, con `tipo` discriminando empleo / freelance / contrato. Columnas: contraparte, título, estado, si está abierta, plataforma, `match_score`, riesgo del cliente, perfil usado, bid o monto, costo de postularse, fechas, **días sin movimiento**, link y la ruta de la nota.
55
+
56
+ Sin `--csv` va a stdout; con `--csv <archivo>` lo escribe en UTF-8 con BOM para que Excel no rompa los acentos. `--tipo` filtra a un solo tipo.
57
+
58
+ `dias_sin_movimiento` es la columna más útil de la planilla: ordenando por ahí aparece lo que quedó colgado.
59
+
60
+ ### `stats` - conteos
61
+
62
+ Total y abiertas por tipo, desglose por estado, cuántas se enviaron y el costo de postulaciones registrado.
63
+
64
+ Trae `muestra_suficiente_para_tasas`: **con menos de 10 enviadas es `false`, y ahí no hay que calcular tasas de conversión**. Diez rechazos no son un patrón, y tratarlos como tal manda al usuario a arreglar lo que no estaba roto.
65
+
66
+ ### `audit` - las divergencias
67
+
68
+ Lo que hace que la trazabilidad sea real y no una intención:
69
+
70
+ - Notas sin `estado` o sin contraparte
71
+ - Enviadas sin fecha de envío (rompe cualquier cálculo de tiempos)
72
+ - **Abiertas frenadas hace 21+ días** - candidatas a follow-up con `/cold-outreach` o a cerrar como `sin_respuesta`
73
+ - Posibles duplicados: misma contraparte, mismo título, dos notas
74
+ - **Contratos con horas reales arriba de lo estimado**, con el exceso en horas y en porcentaje. Cada uno es trabajo regalado si no hubo change order
75
+ - Punteros del dedup que apuntan a notas que ya no existen
76
+
77
+ ## Proceso
78
+
79
+ 1. Correr el modo pedido. Si el workspace no existe, el script lo dice y sugiere `/freelance-hunt setup` o `/job-hunt setup`.
80
+ 2. **Mostrar el resultado en el chat, no solo el JSON crudo.** Para `check`, el veredicto y una línea por coincidencia con su estado. Para `audit`, agrupado por severidad: primero lo que cuesta plata (horas de más, enviadas sin fecha), después lo cosmético.
81
+ 3. Para cada hallazgo de `audit`, ofrecer la acción concreta: follow-up, cerrar como `sin_respuesta`, change order, o completar el campo que falta.
82
+ 4. Los arreglos se hacen **en la nota** con approval del usuario, una por una. Nunca en masa.
83
+
84
+ ## Reglas
85
+
86
+ - **Nunca editar el CSV como si fuera la fuente de verdad.** Se regenera; los cambios van a la nota.
87
+ - **No editar notas en masa.** Cada arreglo se muestra y se aprueba.
88
+ - Nunca inventar un dato que falta: si una nota no tiene fecha de envío, se pregunta o se deja el hueco reportado.
89
+ - No cambiar `estado`: eso lo hace `/job-outcome`, que es el único que mueve el pipeline.
90
+ - El CSV puede tener nombres de clientes y montos: **no commitearlo a un remoto sin confirmación explícita**.
91
+ - Sin guiones largos en el texto agregado a las notas.
92
+
93
+ ## Handoff
94
+
95
+ Pedí aprobación (approval) antes de escribir el CSV o tocar una nota. Registro COMPLETE cuando el modo corrió y el usuario sabe qué hacer con cada hallazgo. Según el caso, el siguiente paso es `/cold-outreach` (follow-up de lo frenado), `/job-outcome` (cerrar lo que no va a responder), `/contract-and-proposal-writer` (change order de las horas de más) o `/freelance-pipeline` (si hay 10+ resueltas y querés el diagnóstico del embudo).