Onboarding guidato per il sistema Job Hunter. Usa questa skill quando un nuovo utente vuole attivare il sistema di ricerca lavoro autonoma: ingerisce il CV, fa domande su vincoli/preferenze (trasferimento, remoto, retribuzione, preavviso, diritto al lavoro, lingue), produce master-profile.yaml e il primo intento di ricerca in searches/ nel repo del sistema, genera e attiva la config della routine job-watch. Trigger su qualsiasi richiesta di avviare/configurare/inizializzare il sistema o la ri...
Scanned 9/4/2026
Install to Claude Code
npx -y skills add FynePool/job-hunter-template --skill agent-config --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Agent Config?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/fynepool-agent-config)More formats (shields.io, HTML) on the badges page.
---
name: agent-config
description: >-
Onboarding guidato per il sistema Job Hunter. Usa questa skill quando un
nuovo utente vuole attivare il sistema di ricerca lavoro autonoma:
ingerisce il CV, fa domande su vincoli/preferenze (trasferimento, remoto,
retribuzione, preavviso, diritto al lavoro, lingue), produce
master-profile.yaml e il primo intento di ricerca in searches/ nel repo
del sistema, genera e attiva la config della routine job-watch. Trigger
su qualsiasi richiesta di avviare/configurare/inizializzare il sistema o
la ricerca lavoro, anche breve o generica — es. "inizializza il
progetto", "salva queste skill e configurami", "iniziamo a fare
job-hunting", "configurami il sistema". Non richiedere che l'utente
nomini "agent-config" o "onboarding": il segnale è l'intento di avviare
il processo. NON usarla per modificare un search-profile già esistente
("aggiorna il mio profilo di ricerca", "cambia i ruoli/le location"):
per quello esiste la skill job-search-profile.
---
# agent-config
Orchestratore conversazionale che porta un utente da zero a sistema attivo (Modulo 1.1 del progetto Job Hunter). Produce i primi artefatti di profilo nel repo del sistema (`master-profile.yaml` nella radice, `searches/defaults.yaml` + il primo `searches/<intent-id>.yaml`) e passa la palla a `job-alert-config` (1.2.1) per la config degli alert.
**Nota architetturale (D5, D7 — da non dimenticare in futuri aggiornamenti)**: architettura a binario unico. TUTTO vive nello stesso repo — profili (`master-profile.yaml`, `searches/`), valutazioni (`role-fit/`), candidature (`applications/`), telemetria operativa (`source-log/`, `state.json`, staging, digest) e le skill stesse sotto `.claude/skills/`. Fatto tecnico che motiva l'impianto: l'integrazione GitHub di base disponibile in chat claude.ai (Impostazioni → Connettori) è di **sola lettura** — sincronizza i contenuti per contesto ma non espone tool di scrittura/commit. Per questo ogni SCRITTURA reale (profili, valutazioni, candidature, stato) avviene in **sessione Claude Code** (Desktop o routine cloud), che ha accesso git nativo indipendente dai connettori di chat. Regola di proprietà: le sessioni interattive scrivono profili/valutazioni/candidature; la routine scrive solo lo strato operativo append-only (log/state/digest/staging).
Non eseguire questa skill silenziosamente: è interattiva per costruzione. Ogni sezione sotto corrisponde a un blocco di domande da fare in chat, una alla volta o in piccoli gruppi coerenti — mai tutte insieme in un unico wall of text.
## Passo 0 — Messaggio di apertura fisso
Prima di qualunque verifica tecnica, invia sempre questo messaggio (adattalo minimamente se necessario, ma mantieni struttura, contenuto e tono):
---
Ciao! 👋 Iniziamo la configurazione del sistema Job Hunter.
Ti spiego prima cosa serve e cosa succederà, così puoi preparare tutto senza interruzioni a metà strada :)
**La casa del sistema è un repository GitHub** 🏠 — un'unica repo (questa, in cui stiamo lavorando ora) contiene tutto: il tuo profilo, le ricerche, le valutazioni, le candidature e la routine automatica. Se stai leggendo questo messaggio in Claude Code, la repo c'è già: la verifico tra un attimo.
⚠️ Una sola cosa può fermarci a metà: se questa cartella non è ancora collegata a una repo GitHub tua (il "remote"), l'ultimo passo — l'attivazione della routine — non può partire, perché la routine legge solo ciò che è stato caricato su GitHub. Te lo dico subito dopo la verifica, così eventualmente crei la repo mentre facciamo il resto: il profilo e le ricerche si scrivono comunque.
**Cosa ti servirà collegato prima di iniziare:**
1. **Gmail** 📧 — necessario alla routine di ricerca automatica per leggere gli alert LinkedIn/Indeed, e per preparare le bozze di follow-up più avanti.
2. **Indeed** 🔍 — necessario alla routine per cercare annunci.
Se non li hai già collegati, puoi farlo da Impostazioni → Connettori. Te li verifico comunque uno per uno tra un attimo.
**Cosa ti chiederò:**
- Il tuo CV 📄 (in qualsiasi formato che riesci a caricare qui in chat)
- Alcune domande su vincoli e preferenze: disponibilità a trasferirti o lavorare da remoto, retribuzione attuale e aspettativa, preavviso, diritto al lavoro nei paesi che ti interessano, lingue
- Conferma su ruoli, location e criteri di esclusione per la ricerca
**Cosa succederà dopo:**
1. Scrivo il tuo profilo nel repo (e lo committo io — non devi toccare git)
2. Ti do le istruzioni per impostare gli alert LinkedIn/Indeed
3. Attiviamo insieme la routine di ricerca automatica — questo passaggio si fa dall'**app desktop di Claude Code** 🖥️ (niente terminale, solo click)
4. Se ti va, ti preparo anche una **board Todoist** 📋 per decidere dal telefono quali offerte scartare e quali portare avanti — è facoltativa, te la propongo alla fine
Da lì in poi il sistema lavora per te: ricevi un digest via email con gli annunci trovati, e usi la chat per valutarli, preparare CV su misura e tenere traccia delle candidature.
Cominciamo dal CV — puoi caricarlo ora? 😊
---
Dopo questo messaggio, procedi comunque con la verifica tecnica concreta delle Precondizioni sotto — il messaggio dichiara i requisiti all'utente, ma non sostituisce il controllo reale via `tool_search`. Non fidarti della sola dichiarazione dell'utente "ce li ho tutti collegati": verificalo.
## Precondizioni
Prima di iniziare l'intervista, verifica CONCRETAMENTE (non a parole) i requisiti del sistema, anche quelli che questa skill non usa direttamente — è il primo punto di contatto interattivo, il posto giusto per bloccare l'intero onboarding se manca qualcosa:
1. **Repo del sistema clonato e git funzionante** — verifica DIRETTAMENTE in Claude Code (nessun `tool_search`, non è un connettore di chat): sei dentro un clone di lavoro del repo, `git` risponde, ed esiste un remote configurato (`git remote -v`). È la casa dell'intero sistema — profili, ricerche, valutazioni, candidature, telemetria della routine. Il remote serve perché la routine cloud legge solo ciò che è committato+pushato (vedi passo 6). Se non c'è un remote, dillo e chiedi all'utente di crearlo/collegarlo (repo GitHub sua, nome a scelta) prima del passo 6: i passi 1–4 scrivono in locale e committano, ma senza push la routine non li vedrebbe.
2. **Gmail** — `tool_search` query "Gmail". Necessario alla routine (lettura alert) e a valle per follow-up/bozze.
3. **Indeed** — `tool_search` query "Indeed jobs". Necessario alla routine per la ricerca.
4. **CV disponibile** — chiedilo come primo passo se non è già stato allegato in chat.
5. **Todoist (facoltativo)** — `tool_search` query "Todoist". Serve solo se
l'utente vuole la board di revisione del passo 6-bis: la sua assenza NON
blocca l'onboarding e non va segnalata come mancanza qui. Verificalo quando
arrivi a quel passo, non prima.
Per Gmail/Indeed mancanti: fermati, dì per nome quale manca e perché serve, e chiedi di collegarlo prima di proseguire. Non generare un profilo incompleto "per ora" e non saltare la verifica assumendo che l'utente li abbia già collegati solo perché ha caricato il pacchetto di skill (il pacchetto e i connettori sono due cose diverse, vedi customer journey passi 2 e 3).
**Connettore o scrittura che fallisce a metà flusso**: se un tool call fallisce durante l'intervista (connettore Gmail/Indeed scaduto, permesso revocato) o se la scrittura/commit al passo 4 fallisce, non perdere il lavoro fatto: mostra subito in chat lo stato completo dei dati raccolti fino a quel punto (lo YAML parziale, se già formato), spiega cosa ha fallito e come rimediare, e riprendi ESATTAMENTE dal passo interrotto — non ricominciare l'intervista da capo. In particolare, se la scrittura file al passo 4 riesce ma il commit no, i file sono comunque salvati in locale: ritenta solo il commit.
## Schema di riferimento
Gli schemi dato-agnostici sono in:
- `references/master-profile.schema.yaml`
- `references/search-profile.schema.yaml`
Leggili prima di condurre l'intervista: ogni campo dello schema è una domanda potenziale. Non inventare campi che non sono nello schema; se durante l'intervista emerge un dato utile che non ha posto nello schema, segnalalo all'utente invece di infilarlo a forza da qualche parte — potrebbe voler dire che lo schema va aggiornato (torna al progetto, non decidere da solo).
## Flusso
### 1. Ingestione CV → bozza master-profile
- Chiedi il CV se non presente.
- Estrai dal CV tutto ciò che mappa direttamente sui campi di `master-profile.schema.yaml`: esperienze, progetti, skill tecniche, lingue, formazione, certificazioni.
- Presenta la bozza risultante e chiedi conferma/correzioni prima di proseguire. Un CV può essere ambiguo o incompleto (date mancanti, stack non esplicito) — segnala i buchi invece di indovinare.
- Non chiedere ancora i campi che il CV non può contenere (retribuzione, preavviso, disponibilità): vengono dopo, sono domande dirette non deducibili da un documento.
### 2. Domande su vincoli e preferenze
Copri, in gruppi tematici separati (non tutto insieme):
**Mobilità**
- Disponibilità trasferimento (sì / no / solo alcune aree — e quali)
- Disponibilità remoto (full remote / ibrido / solo sede / indifferente)
**Economico**
- Retribuzione attuale (valore, lordo/netto, periodicità)
- Aspettativa (range, stesse unità)
- Eventuale flessibilità/note
**Contrattuale**
- Preavviso (durata, eventuali vincoli particolari)
**Legale**
- Cittadinanza/e
- Diritto al lavoro per le aree in cui l'utente vuole cercare (non dare per scontato che coincida con la cittadinanza — un permesso di soggiorno, un passaporto UE aggiuntivo, ecc. possono cambiare la risposta)
**Lingue**
- Livello per ciascuna lingua rilevante, e contesto d'uso (lavorativo quotidiano vs solo letto) — serve sia a `master-profile` sia, a valle, a filtrare gli annunci in `search-profile`
**Adozione AI** (`strato_ai_adoption`)
- Quali strumenti AI usa davvero nel lavoro, in quali contesti (scrittura codice, analisi, automazione, documentazione…), con che livello di autonomia (`uso_base` / `uso_avanzato` / `costruisce_soluzioni_ai_per_altri`) ed eventuali note sull'approccio
- Non è un campo di colore: `cv-tailoring` lo usa per decidere se e come far comparire lo strato AI nel CV quando la JD o l'azienda lo rendono rilevante. Se l'utente non usa strumenti AI, lascia il campo vuoto — è una risposta legittima, non un buco da riempire
**Preferenze generali** (`preferenze_generali`)
- Settori preferiti e settori da evitare **come persona** (vedi la regola di disambiguazione sotto), dimensione azienda preferita (`startup` / `pmi` / `enterprise` / `indifferente`), note libere: obiettivi di carriera, cosa cerca in un ambiente di lavoro, cosa lo farebbe dire di no
- Le legge `role-fit`, che le usa come **peso nel giudizio** di un annuncio, mai come filtro
> **Regola di disambiguazione (settori — due campi, due mestieri).** Ci sono due
> posti che parlano di settori e non sono intercambiabili:
> `master-profile.preferenze_generali.settori_preferiti/settori_da_evitare` sono
> affinità **stabili della persona** e **pesano nel giudizio** (`role-fit`: un
> settore gradito rafforza, uno sgradito diventa una considerazione contraria) —
> non filtrano niente, non fanno sparire nessun annuncio.
> `searches/<intento>.settori.target/esclusi` sono criteri della **singola
> ricerca** e **filtrano la raccolta** (`job-watch` e gli alert).
> In breve: se un settore deve far sparire gli annunci → va nell'intento (passo
> 3); se deve solo spostare il giudizio → va nel master-profile. Dillo
> all'utente quando fai la domanda, così sa cosa sta decidendo: la stessa
> parola in due posti diversi ha due effetti diversi.
Ogni gruppo di domande scrive direttamente nei campi corrispondenti dello schema. Se l'utente salta una domanda o risponde "non so", lascia il campo vuoto/null nello YAML — non riempirlo con un default plausibile.
### 3. Produzione del primo intento di ricerca
A questo punto hai i dati per derivare (non indovinare — derivare, con conferma esplicita) la ricerca. Con D2 la ricerca non è un file unico ma una cartella `searches/` con un `defaults.yaml` condiviso e un file per intento. All'onboarding produci **un solo intento** (l'utente potrà aggiungerne altri dopo, via `job-search-profile`). Le domande NON cambiano: cambia solo dove atterrano le risposte.
Dove atterra cosa (vedi `references/search-profile.schema.yaml`):
- **`searches/defaults.yaml`** (default ereditabili, stabili tra intenti): `esclusioni`, `lingue_annuncio`, `parametri_esecuzione`.
- **`searches/<intent-id>.yaml`** (l'intento): `id` (slug stabile, chiedi/proponi un nome breve — es. `data-engineering-eu` — perché è la chiave che comparirà in log, valutazioni e candidature), `nome` (etichetta leggibile), `stato: attivo`, `creato` (data odierna), più `ruoli_target`, `location_target`, `seniority`, `settori`, `fonti`. All'onboarding l'intento non ha `override` (eredita tutti i defaults); lo si aggiunge solo se in futuro un intento diverge.
I campi da raccogliere (invariati nella sostanza):
- **Seniority**: dagli anni di esperienza e dal tipo di ruoli avuti in `master-profile.esperienze`, proponi un livello (`junior/medio/senior/...`) e chiedi conferma — non scriverlo senza validazione, perché la percezione di seniority dell'utente può differire dal dato grezzo.
- **Ruoli target**: chiedi esplicitamente quali titoli cercare (non dedurli automaticamente dal ruolo attuale — un utente potrebbe voler cambiare ruolo).
- **Location target**: chiedi le aree geografiche di interesse, incrociando con `disponibilita_remoto`/`disponibilita_trasferimento` già raccolti.
- **Esclusioni**: chiedi se ci sono titoli o tipi di contratto da escludere sempre (es. ruoli manageriali, stage) — proponi i default tipici (Head of/Director/VP/C-level, Internship/Traineeship/Stage) ma fai confermare, non assumerli silenziosamente.
- **Settori**: target ed esclusi **per questa ricerca** — sono i settori che filtrano la raccolta, non le affinità della persona raccolte al passo 2 (vedi la regola di disambiguazione lì). Parti da `preferenze_generali.settori_preferiti/da_evitare` come proposta ("li uso anche come criterio di ricerca?") e fai confermare: spesso coincidono, ma un settore gradito non implica che l'utente voglia scartare tutto il resto, e un settore da evitare in generale non sempre va escluso in una ricerca specifica.
- **Fonti**: quali piattaforme sono attive per questo intento (`indeed`, `linkedin_alert`, `indeed_alert`, `career_page`, ciascuna con `attiva: true|false` e una `note` che dica perché). Non è un campo decorativo: `job-alert-config` lo legge davvero e salta le fonti `attiva: false`, e la routine ci decide da dove raccogliere — se resta vuoto, a valle nessuno sa cosa saltare. Proponi la configurazione plausibile dal contesto e **fai confermare** (stessa regola degli altri campi derivati, nessuna assunzione silenziosa): `indeed` normalmente attiva (ricerca diretta via connettore, non richiede setup da parte dell'utente); `linkedin_alert`/`indeed_alert` attive solo se l'utente intende davvero crearli al passo 5 — è la stessa decisione, quindi chiedila qui una volta sola e riusala lì invece di riproporla; `career_page` di norma `attiva: false` all'onboarding (si accende quando `searches/companies.yaml` avrà aziende, aggiunte più avanti con `job-search-profile`).
- **Lingue annuncio**: da `master-profile.lingue`, proponi quali lingue sono accettabili per il corpo di un annuncio e quali lo scartano se prevalenti/obbligatorie — richiede una domanda esplicita, perché "so l'inglese" non implica automaticamente "accetto annunci il cui corpo è in inglese ma richiede altra lingua come requisito".
- **Parametri esecuzione**: finestra temporale e max annunci per esecuzione — proponi i default usati nella routine esistente (48 ore, 15 annunci) solo come punto di partenza dichiarato, fai confermare.
### 4. Scrittura nel repo + commit
- Verifica se esistono già i file di profilo (`master-profile.yaml` nella radice, `searches/`): se sono già valorizzati, l'utente ha probabilmente già fatto l'onboarding — chiedi conferma prima di sovrascrivere, non ripartire da zero in silenzio. (Un `master-profile.yaml` vuoto/placeholder o un `searches/` con solo `defaults.yaml` scaffold NON è "già onboardato": procedi.)
- Mostra il contenuto finale all'utente PRIMA di scriverlo. Non scrivere silenziosamente — è un dato che alimenta tutto il resto del sistema (routine, role-fit, cv-tailoring): un errore qui si propaga ovunque.
- Ultimo atto del passo, eseguito da te (l'utente non tocca git — D7): scrivi i file (`master-profile.yaml`, `searches/defaults.yaml`, `searches/<intent-id>.yaml`) e **committa** con un messaggio chiaro (es. `onboarding: master-profile + primo intento <intent-id>`). Il push si fa al passo 6, quando si attiva la routine (prima non serve: nulla legge ancora questi file da remoto).
### 5. Passaggio a job-alert-config (alert LinkedIn/Indeed)
L'ordine è vincolato, non è una preferenza di stile: prima si scrive il primo intento in `searches/` (passo 4), poi si configurano gli alert, e solo dopo si attiva la routine (passo 6). La routine legge gli alert LinkedIn via Gmail: attivarla prima che gli alert esistano la farebbe partire su una fonte vuota.
- Richiama esplicitamente la skill `job-alert-config` (1.2.1), passandole l'intento appena creato in `searches/`. Non duplicarne la logica qui: quella skill produce le istruzioni su come impostare i campi degli alert su LinkedIn/Indeed (sono dietro login, quindi istruzioni per l'utente, non config programmatica) **e** conduce la scelta guidata sull'**etichetta Gmail** (creata via connettore o a mano) e sul **filtro Gmail** che la applica ai quattro mittenti degli alert — il filtro resta manuale in ogni caso, il connettore non espone tool sui Filtri. Se in quel passaggio si concorda o si cambia il nome dell'etichetta, `routine-config.yaml` viene allineato lì: al passo 6 lo verifichi, non lo richiedi da capo.
- Aspetta conferma esplicita dall'utente che gli alert sono stati effettivamente impostati prima di passare al punto 6. Non proseguire per inerzia.
### 6. Verifica e attivazione della routine
Architettura a **binario unico** (D5): tutto vive in questo repo — i profili (`master-profile.yaml`, `searches/`) scritti al passo 4, e lo strato operativo che la routine scriverà (`source-log/`, `state.json`, staging, digest). Non c'è un secondo storage.
Compiti di questo passo:
- **`routine-config.yaml` (radice del repo, F5) — mostralo e fallo confermare prima di attivare la routine.** È la config operativa che la routine legge a ogni run. Due valori si decidono qui (il terzo blocco, `todoist:`, solo se l'utente accetta la board opzionale del passo 6-bis):
- `gmail_label` — l'etichetta Gmail da cui la routine legge gli alert. Di norma è già stata concordata (e il file già allineato) al passo 5 con `job-alert-config`: qui **verifichi** che il file dica esattamente il nome dell'etichetta che esiste davvero in Gmail, non lo richiedi da capo. Se al passo 5 l'utente ha scelto il percorso manuale e non ha ancora creato etichetta e filtro, questo è l'ultimo momento utile per farglielo notare: attivare la routine con un'etichetta dichiarata ma inesistente produce un'**anomalia nel digest a ogni run**, per sempre. Se l'utente preferisce non usare affatto un'etichetta, lascia il campo vuoto — la routine ha un fallback per mittente ed è un esito legittimo, non un'anomalia; ciò che non deve mai succedere è un nome dichiarato senza etichetta corrispondente.
- `cadenza_dichiarata` — la cadenza che stai per impostare davvero nella routine (es. `"1 run/giorno"`), scritta in chiaro: è il valore con cui il digest calcola la "prossima run attesa" e con cui `job-alert-tuner` confronterà la cadenza reale. Falla confermare insieme alla schedulazione che crei sotto, così i due valori nascono coerenti.
- Se il file **non esiste** nel repo dell'utente, scrivilo tu (D7 — l'utente non tocca file) con i valori confermati, mantenendo i commenti esplicativi: cosa sono i due campi, la trappola dell'operatore `label:` che non accetta l'ID interno di `list_labels` (solo il nome), e il promemoria che l'ambiente della routine cloud deve impostare `JOB_HUNTER_ROUTINE=1` nei propri secret (non è derivabile dal repo). Committalo insieme al resto.
- **Push obbligatorio prima di attivare la routine**: la routine cloud gira su un clone del repo e vede SOLO ciò che è stato committato *e pushato*. Esegui tu il push del commit del passo 4 (D7 — l'utente non tocca git). Se al prerequisito 1 mancava il remote, è il momento di risolverlo: fatti dare l'URL della repo GitHub dell'utente, collegala come remote, poi push. Senza questo, la routine partirebbe su un profilo vuoto.
- **Regola di proprietà (ricordala all'utente)**: da qui in poi la routine scrive solo lo strato operativo append-only (log/state/digest/staging); i profili, le valutazioni e le candidature restano scritti dalle sessioni interattive. La routine *legge* i profili e `applications/` (per le scadenze del digest), non li modifica.
- Guida l'attivazione della routine come Claude Code Routine in cloud, dall'app desktop Claude Code (nessun terminale). Spiega i passaggi a livello di cosa cliccare, non assumere che l'utente sappia già come si crea una routine.
- Mostra, a scopo di verifica, i valori committati al passo 4, così l'utente capisce cosa la routine leggerà dal clone.
### 6-bis. Board Todoist per la revisione (opzionale — proponila, non imporla)
Il collo di bottiglia reale del sistema non è trovare gli annunci: è
**decidere** su quelli trovati, perché lo scarto/promozione richiede una
sessione Claude Code. La board Todoist sposta quella decisione sul telefono:
la routine crea una card per ogni offerta in attesa, l'utente la trascina, e al
giro successivo `scripts/sync_todoist.py` (passo 6-bis di `job-watch`)
rispecchia lo spostamento nel repo. **È opzionale**: senza, il sistema funziona
esattamente come prima (revisione in chat, anche a lotti con il triage di
`application-tracker`). Proponila con una frase sola e accetta il no senza
insistere.
Se l'utente dice sì:
1. **Connettore Todoist** — `tool_search` query "Todoist". Se manca, dillo:
senza connettore puoi comunque procedere, ma la board dovrà crearla lui a
mano e gli ID delle sezioni non sono leggibili dall'interfaccia (l'URL
mostra solo quello del progetto) — quindi in pratica **conviene collegarlo**.
2. **Crea la board tu** (D7 — l'utente non tocca file né configurazioni che
puoi fare tu): un progetto (nome a scelta dell'utente, proponi "Job Hunter")
in **vista board**, con cinque sezioni dai nomi ESATTI, nell'ordine:
`Da valutare · fit forte` · `Da valutare · fit buono` · `Scartate` ·
`Da candidare` · `Candidatura inviata`.
L'anticamera è divisa per fit di proposito: in un blocco unico i due fit forti
della settimana annegano fra ottanta buoni e la board smette di essere una
lista di decisioni. I nomi servono all'utente; il sync lavora sugli **ID**,
così rinominare una sezione più avanti non rompe nulla. Se l'utente ha già un
progetto suo che vuole riusare, usa quello e crea solo le sezioni mancanti.
3. **Scrivi il blocco `todoist:` in `routine-config.yaml`** con `project_id` e i
cinque ID di sezione restituiti dal connettore (schema in
`job-watch/SKILL.md`, passo 6-bis), e committalo insieme al resto:
```yaml
todoist:
project_id: "<id progetto>"
sezioni:
da_valutare_forte: "<id>"
da_valutare_buono: "<id>"
scartate: "<id>"
da_candidare: "<id>"
candidatura_inviata: "<id>"
push_score_minimo: buono
```
`push_score_minimo` è la soglia sotto la quale **non si crea alcuna card**:
con `buono` (default) le offerte `parziale`/`debole` restano in staging nel
repo e si rivedono in chat col triage in blocco di `application-tracker`.
Spiegalo all'utente in una riga: la board resta corta e decidibile, ma **non
è lo specchio completo della coda** — il conteggio delle voci non spinte
compare nel digest. Se vuole vedere tutto sulla board, abbassa la soglia e
aggiungi le sezioni `da_valutare_parziale` / `da_valutare_debole` (il sync
pretende un gruppo per ogni fit sopra soglia, e senza esce 3).
Il **token non va mai qui** (né in nessun altro file del repo).
4. **Dichiara i due passi che restano all'utente** — sono suoi per costruzione,
nessun agente può farli, quindi dillo esplicitamente invece di darli per
scontati:
- **`TODOIST_API_TOKEN`** nei secret dell'ambiente della routine
(in Todoist: Impostazioni → Integrazioni → Sviluppatore → API token;
su claude.ai: routine → icona ambiente → variabili/secret). Stesso
trattamento di `JOB_HUNTER_ROUTINE=1`: non è derivabile dal repo.
- **`api.todoist.com` nel Network access dell'ambiente** della routine cloud
(icona ambiente → Network access → Custom → Allowed domains). È il
**secondo gate**, indipendente da `sandbox.network.allowedDomains` in
`.claude/settings.json` (quello è già committato e copre solo le sessioni
Desktop/locali). Senza, lo script esce con errore di rete a ogni run.
5. **Spiega la semantica in due righe**, perché è ciò che rende la board
affidabile: il push è in **sola creazione** (una card già spostata non torna
mai indietro da sé) e il pull agisce **solo** sul cambio di sezione — quindi
niente si muove nel repo se non lo muove l'utente. Spostare una card fra i
gruppi «Da valutare · fit ...» non è una decisione: il sync la registra e
basta, nel repo non cambia nulla. Se una card viene
spostata in una sezione che non corrisponde allo stato dei file (es. «Da
candidare» su un'offerta già scartata), il sync non forza nulla: lo segnala
nel digest come incongruenza da sistemare a mano.
6. **Cosa fa la promozione da Todoist, e cosa no**: crea la candidatura in
`applications/` con `status: da_candidare`, copia i materiali già generati e
congela un `jd.md` con `completezza: non_disponibile` (lo script non ha il
corpo dell'annuncio e non lo inventa). Restano da fare in chat la cattura
della JD, la persistenza della valutazione in `role-fit/` e la scadenza di
follow-up — per questo la voce di staging resta lì marcata `approved`.
Se l'utente dice no (o rimanda): non scrivere il blocco `todoist:`. Senza
blocco, la routine salta il passo e nota una riga nel digest — nessun errore.
Si può attivare in qualunque momento più avanti, questo passo non è una porta
che si chiude.
### 7. Utente operativo
Solo a questo punto l'onboarding è completo: profilo scritto, alert impostati, routine attiva. Dillo esplicitamente all'utente e ricorda dove vivono i canali con cui interagirà da qui in poi (digest via email, chat per lo Studio, e — se ha attivato il passo 6-bis — la board Todoist per le decisioni rapide: ricordagli che le card compaiono solo dopo la prima run della routine, non subito). Ricorda anche che da qui in poi nulla richiede di rifare l'onboarding: i criteri di ricerca si modificano con `job-search-profile` (e dopo ogni modifica gli alert LinkedIn/Indeed si riallineano con `job-alert-config`), mentre il profilo — nuove esperienze, competenze, certificazioni, RAL aggiornata — si aggiorna con `master-profile-editor`, che lavora per delta senza mai ricostruirlo da zero.
## Cosa NON fare
- Non riempire mai un campo con un valore plausibile ma non confermato dall'utente ("assunzione silenziosa").
- Non usare dati di memoria dell'account per rispondere a domande che l'intervista dovrebbe porre all'utente attivo in quel momento — la skill deve funzionare identica per un utente di cui non sai nulla.
- Non saltare la conferma finale prima della scrittura dei file nel repo.
- Non inventare campi fuori schema: se serve un campo nuovo, fermati e segnalalo invece di forzarlo in un campo esistente.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!