fluncle 0.156.0 → 0.157.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/bin/fluncle.mjs +68 -7
- package/package.json +1 -1
package/bin/fluncle.mjs
CHANGED
|
@@ -561,7 +561,7 @@ function parseVersion(version) {
|
|
|
561
561
|
var currentVersion;
|
|
562
562
|
var init_version = __esm(() => {
|
|
563
563
|
init_output();
|
|
564
|
-
currentVersion = "0.
|
|
564
|
+
currentVersion = "0.157.0".trim() ? "0.157.0".trim() : "0.1.0";
|
|
565
565
|
});
|
|
566
566
|
|
|
567
567
|
// src/update-notifier.ts
|
|
@@ -2189,7 +2189,7 @@ function parseVersion2(version) {
|
|
|
2189
2189
|
var currentVersion2, latestReleaseUrl = "https://api.github.com/repos/mauricekleine/fluncle/releases/latest";
|
|
2190
2190
|
var init_version2 = __esm(() => {
|
|
2191
2191
|
init_output();
|
|
2192
|
-
currentVersion2 = "0.
|
|
2192
|
+
currentVersion2 = "0.157.0".trim() ? "0.157.0".trim() : "0.1.0";
|
|
2193
2193
|
});
|
|
2194
2194
|
|
|
2195
2195
|
// ../../packages/registry/src/index.ts
|
|
@@ -2913,6 +2913,8 @@ var init_src = __esm(() => {
|
|
|
2913
2913
|
name: "cron.enrich",
|
|
2914
2914
|
operatorNotes: "every 5m. Pure compute, zero LLM tokens. Source: docs/agents/hermes/scripts/enrich-sweep.*",
|
|
2915
2915
|
probeConfig: { cadenceMs: 5 * MINUTE_MS, cronName: "fluncle-enrich", kind: "cron" },
|
|
2916
|
+
statusDescription: "BPM, key, and the spectral fingerprint",
|
|
2917
|
+
title: "Audio enrichment",
|
|
2916
2918
|
weights: { status: "hidden" }
|
|
2917
2919
|
},
|
|
2918
2920
|
{
|
|
@@ -2924,6 +2926,8 @@ var init_src = __esm(() => {
|
|
|
2924
2926
|
name: "cron.embed",
|
|
2925
2927
|
operatorNotes: "every 5m. On-box MuQ (torch, ~16s/track), zero LLM tokens. Writes the vector via the agent-tier update_track. Source: docs/agents/hermes/scripts/embed-sweep.* + embed-track.py. See docs/track-lifecycle.md.",
|
|
2926
2928
|
probeConfig: { cadenceMs: 5 * MINUTE_MS, cronName: "fluncle-embed", kind: "cron" },
|
|
2929
|
+
statusDescription: "MuQ vectors for sonic similarity",
|
|
2930
|
+
title: "Audio embeddings",
|
|
2927
2931
|
weights: { status: "hidden" }
|
|
2928
2932
|
},
|
|
2929
2933
|
{
|
|
@@ -2935,6 +2939,8 @@ var init_src = __esm(() => {
|
|
|
2935
2939
|
name: "cron.cluster",
|
|
2936
2940
|
operatorNotes: "nightly (02:20 Amsterdam), run by a rave-02 HOST systemd timer (docs/agents/hermes/cluster-timer/). Assignment-ONLY + idempotent (a no-op on an unchanged corpus): assign each finding to its nearest stored centroid, recompute centroids as members' means, retire an emptied galaxy, consume an operator split_requested_at (a k=2 fit). Zero LLM tokens; sub-second CPU. A full k=9 fit is an OPERATOR act (--cold-start / --remint), never scheduled. Source: docs/agents/hermes/scripts/cluster-sweep.* + cluster.py. See docs/agents/cluster-engine.md.",
|
|
2937
2941
|
probeConfig: { cadenceMs: 24 * 60 * MINUTE_MS, cronName: "fluncle-cluster", kind: "cron" },
|
|
2942
|
+
statusDescription: "groups the archive into sonic galaxies",
|
|
2943
|
+
title: "Sonic galaxies",
|
|
2938
2944
|
weights: { status: "hidden" }
|
|
2939
2945
|
},
|
|
2940
2946
|
{
|
|
@@ -2946,6 +2952,8 @@ var init_src = __esm(() => {
|
|
|
2946
2952
|
name: "cron.crawl",
|
|
2947
2953
|
operatorNotes: "every 10m, run by a rave-02 HOST systemd timer (docs/agents/hermes/crawl-timer/). METADATA ONLY — it writes a `tracks` row with no `findings` row, so it certifies nothing (no Log ID, no note, no video, no public surface) and it captures no audio. Worker-paced (the box holds no MusicBrainz budget): one bounded pass per tick over the durable `crawl_frontier`, so a crawl is a marathon the SCHEDULE finishes and a reboot mid-label costs one node, not one crawl. The boundary gate is the operator's seed-label allowlist + graph distance (hop 0-2), never genre inference; a label the walk discovers enters `undecided` and is NOT crawled until he rules on it. Zero LLM tokens. Source: docs/agents/hermes/scripts/crawl-sweep.*. See docs/catalogue-crawler.md.",
|
|
2948
2954
|
probeConfig: { cadenceMs: 10 * MINUTE_MS, cronName: "fluncle-crawl", kind: "cron" },
|
|
2955
|
+
statusDescription: "charts new tracks from the wider label graph",
|
|
2956
|
+
title: "Track crawler",
|
|
2949
2957
|
weights: { status: "hidden" }
|
|
2950
2958
|
},
|
|
2951
2959
|
{
|
|
@@ -2957,6 +2965,8 @@ var init_src = __esm(() => {
|
|
|
2957
2965
|
name: "cron.rank",
|
|
2958
2966
|
operatorNotes: "every 30m, run by a rave-02 HOST systemd timer (docs/agents/hermes/rank-timer/). THE EAR's schedule, and it lands with the crawler on purpose: a timer ranking an empty table would be a /status row that means nothing, and the crawler is what creates rows. All the vector arithmetic runs in SQL inside the Worker; the sweep DRAINS (it loops while `remaining > 0` up to a tick budget), so a crawl that just landed 700 rows is ranked by the next tick. Self-healing: staleness is a fingerprint of the finding corpus, so logging or embedding a finding re-ranks the catalogue with no invalidation call. Writes DERIVED columns on catalogue rows only — it cannot certify. Zero LLM tokens. Source: docs/agents/hermes/scripts/rank-sweep.*. See docs/the-ear.md.",
|
|
2959
2967
|
probeConfig: { cadenceMs: 30 * MINUTE_MS, cronName: "fluncle-rank", kind: "cron" },
|
|
2968
|
+
statusDescription: "ranks unvisited tracks by nearness to the archive",
|
|
2969
|
+
title: "Track ranking",
|
|
2960
2970
|
weights: { status: "hidden" }
|
|
2961
2971
|
},
|
|
2962
2972
|
{
|
|
@@ -2968,6 +2978,8 @@ var init_src = __esm(() => {
|
|
|
2968
2978
|
name: "cron.label-images",
|
|
2969
2979
|
operatorNotes: "every 60m, run by a rave-02 HOST systemd timer (docs/agents/hermes/label-images-timer/). The DURABLE other half of the label entity: the crawler MINTS new labels every few minutes (each `image_state='pending'`) and the one-shot operator backfill only seeded the labels that already existed, so this cron is what gives every freshly-minted label its OWN logo instead of a borrowed album cover. METADATA ONLY — a label logo is internal, reversible, nominative-use trademark (the album-art posture); it certifies nothing and publishes nothing (agent tier, the `backfill_discogs` precedent). Worker-paced (the box holds no Discogs key / MusicBrainz budget): one bounded batch per tick walks each label's MB identity → its curated Discogs/Wikidata url-rels → downloads the logo once into R2, up the ladder Discogs → Wikidata → none (the freshest-cover floor). The `labels` row carries the durable reliability state (image_state/image_attempted_at/image_failures), so a resolved/none label is terminal and a vendor throttle just circuit-breaks and resumes next tick. Zero LLM tokens. Source: docs/agents/hermes/scripts/label-images-sweep.*. See docs/label-entity.md.",
|
|
2970
2980
|
probeConfig: { cadenceMs: 60 * MINUTE_MS, cronName: "fluncle-label-images", kind: "cron" },
|
|
2981
|
+
statusDescription: "resolves each label's own mark",
|
|
2982
|
+
title: "Label logos",
|
|
2971
2983
|
weights: { status: "hidden" }
|
|
2972
2984
|
},
|
|
2973
2985
|
{
|
|
@@ -2979,6 +2991,8 @@ var init_src = __esm(() => {
|
|
|
2979
2991
|
name: "cron.cover-masters",
|
|
2980
2992
|
operatorNotes: "every 60m, run by a rave-02 HOST systemd timer (docs/agents/hermes/cover-masters-timer/). The DURABLE other half of the album/artist cover (RFC musickit-second-authority U3b): the publish path + catalogue crawl MINT albums/artists (each `image_state='pending'`) and this cron gives each its OWN ≤1200²-capped cover derivative in R2 (found.fluncle.com, `albums/<slug>.<ext>` / `artists/<slug>.<ext>`) instead of hotlinking a third party — the label-logo posture, two entities over. IMAGE ONLY — a downscaled display derivative, reversible, the REF-05-conscious 1200 line (docs/album-artwork.md); it certifies nothing and publishes nothing (agent tier, the `backfill_label_images` precedent). Worker-paced: one bounded batch of albums (Apple template → Cover Art Archive → Spotify floor), then one of artists (Spotify floor), per tick; every rung requests a ≤1200 rendition and a byte read enforces the cap before the R2 put, so no un-downscaled original is ever stored. The `albums`/`artists` row carries the durable reliability state (image_state/image_attempted_at/image_failures), so a resolved/none entity is terminal. Served via Cloudflare Images `/cdn-cgi/image/…` (decision B). Zero LLM tokens. Source: docs/agents/hermes/scripts/cover-masters-sweep.*. See docs/album-artwork.md.",
|
|
2981
2993
|
probeConfig: { cadenceMs: 60 * MINUTE_MS, cronName: "fluncle-cover-masters", kind: "cron" },
|
|
2994
|
+
statusDescription: "owns each album and artist its cover master",
|
|
2995
|
+
title: "Cover masters",
|
|
2982
2996
|
weights: { status: "hidden" }
|
|
2983
2997
|
},
|
|
2984
2998
|
{
|
|
@@ -2990,6 +3004,8 @@ var init_src = __esm(() => {
|
|
|
2990
3004
|
name: "cron.capture",
|
|
2991
3005
|
operatorNotes: "every 5m, run by a rave-02 HOST systemd timer (docs/agents/hermes/capture-timer/) — NOT a gateway cron: a proxied yt-dlp fetch has an unbounded tail that would starve the 5-min enrich/context/note sweeps on the shared serial runner. A NON-BLOCKING side-channel (never gates enrich/embed). Runs yt-dlp through a residential proxy on a per-track sticky session, duration-guards the match, stores the full song in the PRIVATE fluncle-source-audio bucket (S3-direct), and writes back via the agent-tier update_track (with per-finding backoff). yt-dlp + ffprobe are a box deploy prereq. Newest-first so a fresh add jumps the backfill. Source: docs/agents/hermes/scripts/capture-sweep.*. See docs/track-lifecycle.md.",
|
|
2992
3006
|
probeConfig: { cadenceMs: 5 * MINUTE_MS, cronName: "fluncle-capture", kind: "cron" },
|
|
3007
|
+
statusDescription: "captures each finding's full song once",
|
|
3008
|
+
title: "Full-song capture",
|
|
2993
3009
|
weights: { status: "hidden" }
|
|
2994
3010
|
},
|
|
2995
3011
|
{
|
|
@@ -3001,6 +3017,8 @@ var init_src = __esm(() => {
|
|
|
3001
3017
|
name: "cron.verify-captures",
|
|
3002
3018
|
operatorNotes: "every 30m, run by a rave-02 HOST systemd timer (docs/agents/hermes/verify-captures-timer/). The HISTORIC half of the capture verification gate (docs/the-ear.md § Wrong audio): the capture sweep verifies every NEW download at ingest, and this sweep walks every capture that landed before the gate existed and gives each the same Chromaprint check against the track's ISRC-resolved official preview. The box only MEASURES (fpcalc + the sliding-window match) and reports a plain verdict; the Worker ROUTES it — match/no-preview stamp `capture_verification`, a CATALOGUE mismatch quarantines for re-capture, a FINDING mismatch only raises the `capture-suspect` /admin attention item (a machine never rewinds a public finding; the operator rules with flag_wrong_audio). Resumable by construction (a stamped row leaves the worklist); degrades honestly without fpcalc (pre-rebake: `fpcalc_missing`, nothing stamped). Zero LLM tokens. Source: docs/agents/hermes/scripts/verify-captures.* + fingerprint-match.ts. See docs/the-ear.md.",
|
|
3003
3019
|
probeConfig: { cadenceMs: 30 * MINUTE_MS, cronName: "fluncle-verify-captures", kind: "cron" },
|
|
3020
|
+
statusDescription: "checks each captured song against its official preview",
|
|
3021
|
+
title: "Capture verification",
|
|
3004
3022
|
weights: { status: "hidden" }
|
|
3005
3023
|
},
|
|
3006
3024
|
{
|
|
@@ -3012,6 +3030,8 @@ var init_src = __esm(() => {
|
|
|
3012
3030
|
name: "cron.context-note",
|
|
3013
3031
|
operatorNotes: "every 5m. --no-agent trigger; the Worker does the Firecrawl + Haiku distill. Zero on-box tokens.",
|
|
3014
3032
|
probeConfig: { cadenceMs: 5 * MINUTE_MS, cronName: "fluncle-context-note", kind: "cron" },
|
|
3033
|
+
statusDescription: "distills the facts behind each finding",
|
|
3034
|
+
title: "Context notes",
|
|
3015
3035
|
weights: { status: "hidden" }
|
|
3016
3036
|
},
|
|
3017
3037
|
{
|
|
@@ -3023,6 +3043,8 @@ var init_src = __esm(() => {
|
|
|
3023
3043
|
name: "cron.note",
|
|
3024
3044
|
operatorNotes: "every 10m. Hybrid --no-agent; one claude -p authors the line. Never clobbers an operator note.",
|
|
3025
3045
|
probeConfig: { cadenceMs: 10 * MINUTE_MS, cronName: "fluncle-note", kind: "cron" },
|
|
3046
|
+
statusDescription: "writes each finding's editorial note",
|
|
3047
|
+
title: "Editorial notes",
|
|
3026
3048
|
weights: { status: "hidden" }
|
|
3027
3049
|
},
|
|
3028
3050
|
{
|
|
@@ -3032,8 +3054,10 @@ var init_src = __esm(() => {
|
|
|
3032
3054
|
],
|
|
3033
3055
|
kind: "cron",
|
|
3034
3056
|
name: "cron.artist-bio",
|
|
3035
|
-
operatorNotes: "every 30m. Hybrid --no-agent; one claude -p authors the paragraph
|
|
3057
|
+
operatorNotes: "every 30m. Hybrid --no-agent; one claude -p authors the paragraph, its grounding assembled WORKER-side (Firecrawl facts + the artist's finding titles) via the draft-bio op. Never clobbers an operator bio. Live. Source: docs/agents/hermes/scripts/{entity-bio-sweep.ts,artist-bio-sweep.sh}.",
|
|
3036
3058
|
probeConfig: { cadenceMs: 30 * MINUTE_MS, cronName: "fluncle-artist-bio", kind: "cron" },
|
|
3059
|
+
statusDescription: "writes each artist's voiced bio",
|
|
3060
|
+
title: "Artist bios",
|
|
3037
3061
|
weights: { status: "hidden" }
|
|
3038
3062
|
},
|
|
3039
3063
|
{
|
|
@@ -3043,8 +3067,10 @@ var init_src = __esm(() => {
|
|
|
3043
3067
|
],
|
|
3044
3068
|
kind: "cron",
|
|
3045
3069
|
name: "cron.label-bio",
|
|
3046
|
-
operatorNotes: "every 30m. Hybrid --no-agent; one claude -p authors the paragraph
|
|
3070
|
+
operatorNotes: "every 30m. Hybrid --no-agent; one claude -p authors the paragraph, its grounding assembled WORKER-side (Firecrawl facts + the label's finding titles) via the draft-bio op. Never clobbers an operator bio. Live. Source: docs/agents/hermes/scripts/{entity-bio-sweep.ts,label-bio-sweep.sh}.",
|
|
3047
3071
|
probeConfig: { cadenceMs: 30 * MINUTE_MS, cronName: "fluncle-label-bio", kind: "cron" },
|
|
3072
|
+
statusDescription: "writes each label's voiced bio",
|
|
3073
|
+
title: "Label bios",
|
|
3048
3074
|
weights: { status: "hidden" }
|
|
3049
3075
|
},
|
|
3050
3076
|
{
|
|
@@ -3056,6 +3082,8 @@ var init_src = __esm(() => {
|
|
|
3056
3082
|
name: "cron.triage",
|
|
3057
3083
|
operatorNotes: "every 15m. Hybrid --no-agent; a deterministic archive dedupe + DnB-plausibility heuristic feeds one claude -p phrasing, length-gated. Writes the verdict onto a PENDING submission so it lands in the /admin attention queue already assessed; approve/reject stays operator tier. Source: docs/agents/hermes/scripts/triage-sweep.{sh,ts}.",
|
|
3058
3084
|
probeConfig: { cadenceMs: 15 * MINUTE_MS, cronName: "fluncle-triage", kind: "cron" },
|
|
3085
|
+
statusDescription: "pre-chews each crew submission's verdict",
|
|
3086
|
+
title: "Submission triage",
|
|
3059
3087
|
weights: { status: "hidden" }
|
|
3060
3088
|
},
|
|
3061
3089
|
{
|
|
@@ -3072,6 +3100,8 @@ var init_src = __esm(() => {
|
|
|
3072
3100
|
kind: "cron",
|
|
3073
3101
|
schedule: { time: "00:40", tz: "Europe/Amsterdam" }
|
|
3074
3102
|
},
|
|
3103
|
+
statusDescription: "writes each sector-day up in the Logbook",
|
|
3104
|
+
title: "Logbook author",
|
|
3075
3105
|
weights: { status: "hidden" }
|
|
3076
3106
|
},
|
|
3077
3107
|
{
|
|
@@ -3083,6 +3113,8 @@ var init_src = __esm(() => {
|
|
|
3083
3113
|
name: "cron.observation",
|
|
3084
3114
|
operatorNotes: "every 60m. Hybrid --no-agent; one claude -p authors the script, the Worker voice-gates + renders.",
|
|
3085
3115
|
probeConfig: { cadenceMs: 60 * MINUTE_MS, cronName: "fluncle-observation", kind: "cron" },
|
|
3116
|
+
statusDescription: "Fluncle's spoken field observations",
|
|
3117
|
+
title: "Audio observations",
|
|
3086
3118
|
weights: { status: "hidden" }
|
|
3087
3119
|
},
|
|
3088
3120
|
{
|
|
@@ -3092,6 +3124,8 @@ var init_src = __esm(() => {
|
|
|
3092
3124
|
name: "cron.backfill",
|
|
3093
3125
|
operatorNotes: "every 30m. Pure HTTP driving, zero LLM tokens. Agent tier.",
|
|
3094
3126
|
probeConfig: { cadenceMs: 30 * MINUTE_MS, cronName: "fluncle-backfill", kind: "cron" },
|
|
3127
|
+
statusDescription: "repairs Discogs ids and Last.fm loves",
|
|
3128
|
+
title: "Metadata backfill",
|
|
3095
3129
|
weights: { status: "hidden" }
|
|
3096
3130
|
},
|
|
3097
3131
|
{
|
|
@@ -3102,6 +3136,8 @@ var init_src = __esm(() => {
|
|
|
3102
3136
|
name: "cron.artist-sweep",
|
|
3103
3137
|
operatorNotes: "every 60m. --no-agent trigger; the Worker does the MB walk + Firecrawl /v2/extract + YouTube channel resolution. Zero on-box tokens. MB rows land as status=auto (trusted); Firecrawl rows as status=candidate (operator-confirm before public). Source: docs/agents/hermes/scripts/artist-sweep.*",
|
|
3104
3138
|
probeConfig: { cadenceMs: 60 * MINUTE_MS, cronName: "fluncle-artist-sweep", kind: "cron" },
|
|
3139
|
+
statusDescription: "resolves each artist's socials and identity links",
|
|
3140
|
+
title: "Artist resolution",
|
|
3105
3141
|
weights: { status: "hidden" }
|
|
3106
3142
|
},
|
|
3107
3143
|
{
|
|
@@ -3113,6 +3149,8 @@ var init_src = __esm(() => {
|
|
|
3113
3149
|
name: "cron.social-capture",
|
|
3114
3150
|
operatorNotes: "every 10m. Pure HTTP trigger, zero LLM tokens. Agent tier (fills the public URL only — publishes nothing). The box's baked CLI predates the `--capture` verb, so the cron curls POST /api/admin/social/posts/capture directly; the Worker polls Postiz and writes back. Source: docs/agents/hermes/scripts/social-capture-sweep.sh. Probed on /status as cron.social-capture.",
|
|
3115
3151
|
probeConfig: { cadenceMs: 10 * MINUTE_MS, cronName: "fluncle-social-capture", kind: "cron" },
|
|
3152
|
+
statusDescription: "the live YouTube and TikTok URLs for each posted video",
|
|
3153
|
+
title: "Social links",
|
|
3116
3154
|
weights: { status: "hidden" }
|
|
3117
3155
|
},
|
|
3118
3156
|
{
|
|
@@ -3123,6 +3161,8 @@ var init_src = __esm(() => {
|
|
|
3123
3161
|
name: "cron.studio-clip",
|
|
3124
3162
|
operatorNotes: "every 15m. Pure-trigger, zero LLM tokens: a deterministic ffmpeg cut driven by the fluncle CLI (`admin clips list` → `admin clips cut`), agent-scoped (list_clips + the agent-tier presign_clip_upload / finalize_clip_cut). Cuts the operator-framed 9:16 clips from the /admin/studio editor (keyed by Log ID) out of the set video → ships `<clipId>/footage.mp4` to R2 for the /admin/clips library + the clip drip-feed. The box runs the standalone bun BINARY (the npm thin client can't spawn ffmpeg). Source: docs/agents/hermes/scripts/clip-sweep.sh. Probed on /status as cron.studio-clip.",
|
|
3125
3163
|
probeConfig: { cadenceMs: 15 * MINUTE_MS, cronName: "fluncle-studio-clip", kind: "cron" },
|
|
3164
|
+
statusDescription: "cuts set videos into 9:16 clips",
|
|
3165
|
+
title: "Studio clips",
|
|
3126
3166
|
weights: { status: "hidden" }
|
|
3127
3167
|
},
|
|
3128
3168
|
{
|
|
@@ -3134,6 +3174,8 @@ var init_src = __esm(() => {
|
|
|
3134
3174
|
name: "cron.clip-drip",
|
|
3135
3175
|
operatorNotes: "every 20m. Pure HTTP trigger, zero LLM tokens. Admin tier (needs the Worker's Postiz key, which the box never sees — the box only triggers; the `finalize_clip_cut` / `record_health` precedent). The Worker checks the global kill switch FIRST (paused → no-op), then posts due clips bounded by a per-tick cap AND a rolling-24h IG cap. Every clip auto-enters the schedule at a jittered ~23-25h after the queue tail. The operator pauses/resumes with `fluncle admin clips drip-pause` / `drip-resume`. Source: docs/agents/hermes/scripts/clip-drip-sweep.sh. Probed on /status as cron.clip-drip.",
|
|
3136
3176
|
probeConfig: { cadenceMs: 20 * MINUTE_MS, cronName: "fluncle-clip-drip", kind: "cron" },
|
|
3177
|
+
statusDescription: "drip-feeds set clips to Instagram",
|
|
3178
|
+
title: "Clip drip-feed",
|
|
3137
3179
|
weights: { status: "hidden" }
|
|
3138
3180
|
},
|
|
3139
3181
|
{
|
|
@@ -3145,6 +3187,8 @@ var init_src = __esm(() => {
|
|
|
3145
3187
|
name: "cron.publish-advance",
|
|
3146
3188
|
operatorNotes: "every 30m. Pure HTTP trigger, zero LLM tokens. The last autonomy gap: render finishes → this pushes, with no operator beat between. Admin tier (needs the Worker's Postiz key, which the box never sees — the box only triggers; the `drip_clips` / `capture_post_urls` precedent). SHIPS DARK: the Worker's kill switch is DEFAULT-DENY (only an explicit `false` in the `publish_advance_paused` setting runs it), so the timer ticks and posts nothing until `fluncle admin publish resume`. The Worker reads the switch FIRST, then advances at most ONE ready finding — both masters finalized, 15m settled, the whole bundle served on R2, the (track, platform) row CLAIMED atomically before any Postiz call, a rolling-24h cap of 6 pushes. A failed push is left `failed` for the operator and never auto-retried. Source: docs/agents/hermes/scripts/publish-advance-sweep.sh. Probed on /status as cron.publish-advance.",
|
|
3147
3189
|
probeConfig: { cadenceMs: 30 * MINUTE_MS, cronName: "fluncle-publish-advance", kind: "cron" },
|
|
3190
|
+
statusDescription: "advances the publish queue on his own clock",
|
|
3191
|
+
title: "Publish advance",
|
|
3148
3192
|
weights: { status: "hidden" }
|
|
3149
3193
|
},
|
|
3150
3194
|
{
|
|
@@ -3156,6 +3200,8 @@ var init_src = __esm(() => {
|
|
|
3156
3200
|
name: "cron.render",
|
|
3157
3201
|
operatorNotes: "every 60m. A conductor: triggers a detached @fluncle-video render on a scale-to-zero box.ascii box (rave-03). Never posts to social (operator-tier 403). Probed on /status as service `cron.render` (its own last-run freshness); the box's reachability is the SEPARATE `render-box` probe (the conductor state file).",
|
|
3158
3202
|
probeConfig: { cadenceMs: 60 * MINUTE_MS, cronName: "fluncle-render", kind: "cron" },
|
|
3203
|
+
statusDescription: "the conductor's last run",
|
|
3204
|
+
title: "Render cron",
|
|
3159
3205
|
weights: { status: "hidden" }
|
|
3160
3206
|
},
|
|
3161
3207
|
{
|
|
@@ -3166,6 +3212,8 @@ var init_src = __esm(() => {
|
|
|
3166
3212
|
name: "cron.healthcheck",
|
|
3167
3213
|
operatorNotes: "every 10m, run by a rave-02 host systemd timer (docs/agents/hermes/healthcheck-timer/) — decoupled from the Hermes cron gateway so the prober isn't starved by the scheduler it monitors. Pure probing, zero LLM tokens. POSTs to the agent-tier record_health op that /status reads.",
|
|
3168
3214
|
probeConfig: { cadenceMs: 10 * MINUTE_MS, cronName: "fluncle-healthcheck", kind: "cron" },
|
|
3215
|
+
statusDescription: "the prober behind this very page",
|
|
3216
|
+
title: "Healthcheck prober",
|
|
3169
3217
|
weights: { status: "hidden" }
|
|
3170
3218
|
},
|
|
3171
3219
|
{
|
|
@@ -3182,6 +3230,8 @@ var init_src = __esm(() => {
|
|
|
3182
3230
|
kind: "cron",
|
|
3183
3231
|
schedule: { time: "15:00", tz: "Europe/Amsterdam", weekday: 5 }
|
|
3184
3232
|
},
|
|
3233
|
+
statusDescription: "drafts the Friday edition",
|
|
3234
|
+
title: "Weekly newsletter",
|
|
3185
3235
|
weights: { status: "secondary" }
|
|
3186
3236
|
},
|
|
3187
3237
|
{
|
|
@@ -3197,6 +3247,8 @@ var init_src = __esm(() => {
|
|
|
3197
3247
|
kind: "cron",
|
|
3198
3248
|
schedule: { time: "03:00", tz: "Europe/Amsterdam" }
|
|
3199
3249
|
},
|
|
3250
|
+
statusDescription: "a daily off-site snapshot of the archive",
|
|
3251
|
+
title: "Database backup",
|
|
3200
3252
|
weights: { status: "secondary" }
|
|
3201
3253
|
},
|
|
3202
3254
|
{
|
|
@@ -3213,6 +3265,8 @@ var init_src = __esm(() => {
|
|
|
3213
3265
|
kind: "cron",
|
|
3214
3266
|
schedule: { time: "04:00", tz: "Europe/Amsterdam" }
|
|
3215
3267
|
},
|
|
3268
|
+
statusDescription: "counts the crew and how far the probes reached",
|
|
3269
|
+
title: "Reach snapshot",
|
|
3216
3270
|
weights: { status: "secondary" }
|
|
3217
3271
|
},
|
|
3218
3272
|
{
|
|
@@ -3228,6 +3282,8 @@ var init_src = __esm(() => {
|
|
|
3228
3282
|
kind: "cron",
|
|
3229
3283
|
schedule: { time: "01:00", tz: "Europe/Amsterdam" }
|
|
3230
3284
|
},
|
|
3285
|
+
statusDescription: "nightly one-domain codebase audit → a PR",
|
|
3286
|
+
title: "Nightly audit",
|
|
3231
3287
|
weights: { status: "secondary" }
|
|
3232
3288
|
},
|
|
3233
3289
|
{
|
|
@@ -3243,6 +3299,8 @@ var init_src = __esm(() => {
|
|
|
3243
3299
|
kind: "cron",
|
|
3244
3300
|
schedule: { time: "05:00", tz: "Europe/Amsterdam" }
|
|
3245
3301
|
},
|
|
3302
|
+
statusDescription: "reviews + merges the nightly audit PR",
|
|
3303
|
+
title: "Audit reviewer",
|
|
3246
3304
|
weights: { status: "secondary" }
|
|
3247
3305
|
}
|
|
3248
3306
|
];
|
|
@@ -5832,7 +5890,7 @@ __export(exports_admin_catalogue, {
|
|
|
5832
5890
|
async function catalogueRankCommand(options) {
|
|
5833
5891
|
const limit = options.limit ? Number.parseInt(options.limit, 10) : undefined;
|
|
5834
5892
|
const response = await adminApiPost("/api/admin/catalogue/rank", limit ? { limit } : {});
|
|
5835
|
-
return response.summary;
|
|
5893
|
+
return { summary: response.summary, telescope: response.telescope };
|
|
5836
5894
|
}
|
|
5837
5895
|
async function catalogueListCommand(options) {
|
|
5838
5896
|
const params = new URLSearchParams;
|
|
@@ -10891,14 +10949,17 @@ async function runGalaxies(slug, options, commands) {
|
|
|
10891
10949
|
}
|
|
10892
10950
|
}
|
|
10893
10951
|
async function runCatalogueRank(options, catalogueRankCommand2) {
|
|
10894
|
-
const summary = await catalogueRankCommand2({ limit: options.limit });
|
|
10952
|
+
const { summary, telescope } = await catalogueRankCommand2({ limit: options.limit });
|
|
10895
10953
|
if (options.json) {
|
|
10896
|
-
printJson({ ok: true, summary });
|
|
10954
|
+
printJson({ ok: true, summary, telescope });
|
|
10897
10955
|
return;
|
|
10898
10956
|
}
|
|
10899
10957
|
const quarantine = summary.quarantined > 0 ? ` Quarantined ${summary.quarantined} as wrong audio.` : "";
|
|
10900
10958
|
const deduped = summary.catalogueDuplicates > 0 ? ` Marked ${summary.catalogueDuplicates} as catalogue duplicates.` : "";
|
|
10901
10959
|
console.log(`Ranked ${summary.scored} against ${summary.embeddedFindings} embedded findings; prioritized ${summary.prioritized} for capture.${quarantine}${deduped} ${summary.remaining} still stale.`);
|
|
10960
|
+
if (telescope) {
|
|
10961
|
+
console.log(telescope.ok ? `Telescope: ${telescope.size} aboard${telescope.changed ? " (updated)" : ""}.` : `Telescope: sync failed \u2014 ${telescope.reason}`);
|
|
10962
|
+
}
|
|
10902
10963
|
}
|
|
10903
10964
|
async function runCatalogueList(options, catalogueListCommand2) {
|
|
10904
10965
|
const { summary, tracks } = await catalogueListCommand2({
|
package/package.json
CHANGED