feat(jb_outbound): attribution département + fil d'activité → main - #7
Merged
Conversation
Quand une interception a lieu pendant un job cron (skill/casquette), le DraftRequest porte desormais le departement de la tache : champs ADDITIFS de premier niveau `department`, `skill_id`, `job_id` (omis hors contexte job — chat libre ; le daemon Go actuel ignore les champs inconnus). - job_context.py : ContextVar du job courant, posee par le scheduler au lancement du job. ContextVar et PAS env : les jobs cron tournent dans des THREADS du gateway (pool parallele de tick()) — os.environ s'ecraserait entre jobs concurrents. Hermes propage deja le contexte a chaque saut de thread (copy_context dans _run_job_impl, propagate_context_to_thread pour les outils) → la valeur est visible du middleware pendant tout le job. - Casquette lue dans le front-matter du skill du job : `casquette:` (gold) puis `department:` (custom). Resolution best-effort, parser minimal autonome (pas de dependance yaml ni du coeur) ; toute erreur → champs absents, jamais d'exception. - cron/scheduler.py : pont OPTIONNEL _jb_job_hooks() dans run_job — resout le module DEJA charge par le PluginManager (hermes_plugins.jb_outbound), jamais d'import a froid : sans plugin, comportement stock inchange. Double garde : un hook ne bloque ni ne fait echouer un job. Tests : 9 nouveaux (stamp present/absent/efface, gold/custom/sans casquette, categorie, passif, pont scheduler reel) ; suite 21/21. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
POST fire-and-forget vers http://{JB_DRAFT_ADDR}/v1/activity au debut et a
la fin de chaque job cron (et uniquement cron) :
{phase: started|finished, status: ok|error, department?, skill_id?,
job_id?, label?} — label = nom lisible du job (jobs.json), champs
d attribution OMIS quand absents (meme convention que le stamp des drafts).
- GATED par JB_ACTIVITY_EVENTS=1, defaut OFF : la route daemon n existe pas
encore (vague 2). Timeout 2 s, toute exception avalee (log debug au
plus) — un signal d activite ne bloque ni ne fait echouer JAMAIS un job.
- activity.py : gate + emission ; config.py : activity_url() ;
job_context.job_started/job_finished : emission cablée sur le cycle de
vie du job (status ok au started, ok/error au finished selon le
succes du run).
Tests : +6 (gate OFF par defaut, started→finished avec payload complet,
status error, echec reseau avale sans casser le contexte, emit sans
contexte, pont scheduler reel ok/error) ; suite 27/27.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…vite Documente le stamp des DraftRequest (department/skill_id/job_id), les signaux /v1/activity et le gate JB_ACTIVITY_EVENTS ; precise que la greffe compte desormais un point optionnel dans cron/scheduler.py (no-op sans plugin) et la commande de test Windows. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat(jb_outbound): attribution département + fil d'activité
🔎 Lint report:
|
| Rule | Count |
|---|---|
unresolved-import |
5 |
invalid-argument-type |
1 |
First entries
plugins/jb_outbound/test_attribution_activity.py:15: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
plugins/jb_outbound/test_attribution_activity.py:24: [unresolved-import] unresolved-import: Cannot resolve imported module `jb_outbound.job_context`
plugins/jb_outbound/test_attribution_activity.py:23: [unresolved-import] unresolved-import: Cannot resolve imported module `jb_outbound.http_client`
plugins/jb_outbound/job_context.py:78: [invalid-argument-type] invalid-argument-type: Argument to bound method `ContextVar.reset` is incorrect: Expected `Token[dict[str, Any] | None]`, found `~None`
plugins/jb_outbound/test_attribution_activity.py:25: [unresolved-import] unresolved-import: Cannot resolve imported module `jb_outbound.middleware`
plugins/jb_outbound/test_attribution_activity.py:22: [unresolved-import] unresolved-import: Cannot resolve imported module `jb_outbound.activity`
✅ Fixed issues: none
Unchanged: 5401 pre-existing issues carried over.
Diagnostics are surfaced as warnings — this check never fails the build.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
@
Fait remonter dans
mainle travail mergé sur la branche guardrail par #6 : stampdepartment/skill_id/job_idsur les drafts (ContextVar posée dansrun_job, casquette lue du front-matter SKILL.md) + hooks dactivité début/fin de job (gatedJB_ACTIVITY_EVENTS, fire-and-forget). Le garde-fou lui-même était déjà dans main (#3).Côté plateforme, toute la chaîne consommatrice est déjà sur le main du monorepo (PR NousResearch#55 attribution, NousResearch#60 fil dactivité).
🤖 Generated with Claude Code
@