Tune learning
Change how readily Hiring Signals suggests setting changes. Thresholds, turning signals off, declaring limits, rejecting versus switching learning off, and getting a new definition onto the Desk.
Hiring Signals ships with "learning": {"enabled": true} and every default. This guide changes those defaults, shows what lint says about each change, and gets the new values to the routine’s runs. For what learning is and how it decides, read Learning first.
RO=skills/routineos/scripts/routineos.py
Where the values live
| What | Where | Who changes it |
|---|---|---|
| Thresholds, signals, limits | learning block in definition.json, compiled into meta/definition |
The routine’s builder, then recompile and reseed |
| Whole-Desk off switch | values.learning: false in settings/workspace |
People. As of 0.6.0 the Desk has no control for it |
| One suggestion | Reject or Snooze on Suggestions | People |
| Setting values | settings/hiring-signals |
People, on Settings or by accepting a suggestion |
learn and write read the compiled definition from meta/definition in the store snapshot (unless --definition is given). Editing definition.json changes nothing until the new definition is in the store.
1. Decide what to change
Start from what people see on the Desk:
| What you see | Likely change |
|---|---|
| No suggestions after weeks of people keeping dropped roles | Lower minSample or minEffect |
| A suggestion after two or three keeps that turned out to be noise | Raise minSample |
| The same rejected idea comes back too soon | Raise cooldownDays |
| “Remove X from markets” for a market that is just quiet | Raise deadAfterRuns, or turn dead_item off |
| More than a couple of suggestions per run | Lower maxPerRun |
| Inbox overflows every run and nothing suggests a higher cap | Declare max_inbox_per_run in limits |
2. Edit the learning block
For Hiring Signals: suggest sooner, hold rejected ideas back for a month, stop dead-item suggestions, and let learning tune the Inbox cap.
"learning": {
"enabled": true,
"minSample": 3,
"cooldownDays": 30,
"signals": {"dead_item": false},
"limits": ["max_inbox_per_run"]
}
python3 $RO lint hiring-signals
ok: no problems
max_inbox_per_run can be a limit because Hiring Signals declares it as a number setting (default 5, min 0, max 20). limit_pressure proposes the cap plus the largest overflow seen, never above max.
3. What lint refuses
Each line below is the real output for the change shown.
A misspelled key:
"learning": {"enabled": true, "minsample": 3}
FAIL definition.json: learning: unknown key 'minsample'
A signal that does not exist:
"learning": {"enabled": true, "signals": {"people_dropped": true}}
FAIL definition.json: learning.signals: unknown signal 'people_dropped' (known: override, uncaptured_term, dead_item, source_health, limit_pressure, connections, edit_drift, manual_repetition, people_drop)
Since 0.5.0,
people_dropis the ninth signal, withexcluded_title_wordsin the jobs-watch template.
Numbers out of range:
"learning": {"enabled": true, "maxPerRun": 12, "minEffect": 1.5}
FAIL definition.json: learning.maxPerRun must be a whole number of 0 to 10
FAIL definition.json: learning.minEffect must be a share above 0 and at most 1
A limit learning cannot tune:
"learning": {"enabled": true, "limits": ["lookback_days"]}
FAIL definition.json: learning.limits: 'lookback_days' is not a limit learning can tune (known: max_inbox_per_run)
A setting bound in settingFilters whose name contains push, gate, send, alert, permission, budget, maxruns or capoverride is refused with learning: <name> is never learnable; remove its binding or turn learning off.
4. Get the new definition into the store
python3 $RO compile hiring-signals
python3 $RO seed hiring-signals --out hiring-signals/seed --docs snapshot.json
compile prints a new version id. seed rewrites meta/definition; with --docs holding the current store documents, it keeps every setting people saved and writes settings defaults only where absent. Apply the batch to the Desk’s artifact. The next run reads the new values.
Turning a signal off takes effect from the next run that reads the new definition.
5. Reject, snooze or switch off
| Want | Do | Effect |
|---|---|---|
| Stop one idea for a while | Reject on Suggestions (or Dismiss on the Inbox) | Its key is blocked for cooldownDays |
| Stop one idea until later | Snooze | Blocked until until, 7 days on the Desk |
| Stop one kind of idea | Turn its signal off in the definition | That signal stops proposing |
| Stop all ideas on this Desk | values.learning: false in settings/workspace |
Tallies still count; nothing is proposed; write refuses every proposal message |
| Stop learning for one routine | "enabled": false in its definition |
That producer proposes nothing |
Prefer Reject. It keeps the rest of learning working and its memory is per key. A set proposal is keyed by setting alone, so rejecting “set to 8” also blocks “set to 9”.
The Desk has no switch for values.learning: false as of 0.6.0. Changing it means writing settings/workspace from a session, and that document is people-owned: a run must never write it.
6. Check it worked
After the next run, look at the Suggestions page and the run record (runs/<runId>):
- With
minSampleat 3, three kept roles sharing a word the include filter missed raise anuncaptured_termsuggestion, if their share is at leastminEffect(0.6 by default). - A rejected key does not return within 30 days.
- No
dead_itemsuggestions appear.
If nothing changes, check that the new meta/definition was applied: the run record carries definitionVersion.
Common pitfalls
- Editing
definition.jsonand expecting the next run to see it. Recompile and reseed. - Seeding without
--docs. Seed keeps saved settings only when it can see them. Without a snapshot it cannot tell which settings exist, so it plans defaults for all of them. - Setting
minSampleto 1. One keep becomes a suggestion. People stop reading the Suggestions page. - Turning learning off to stop one suggestion. Reject it.
- Binding a send or gate setting to a filter. It is never learnable, and lint refuses the binding while learning is on.