greprag 5.53.0 → 5.54.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/dist/codex-steering.js +33 -7
- package/dist/codex-steering.js.map +1 -1
- package/dist/commands/arm-reminder.js +1 -1
- package/dist/commands/arm-reminder.js.map +1 -1
- package/dist/commands/codex-delivery.d.ts +2 -1
- package/dist/commands/codex-delivery.js +130 -7
- package/dist/commands/codex-delivery.js.map +1 -1
- package/dist/commands/codex-doctor.js +28 -11
- package/dist/commands/codex-doctor.js.map +1 -1
- package/dist/commands/codex-supervisor.d.ts +6 -1
- package/dist/commands/codex-supervisor.js +37 -12
- package/dist/commands/codex-supervisor.js.map +1 -1
- package/dist/commands/codex-wake-test.d.ts +19 -0
- package/dist/commands/codex-wake-test.js +34 -0
- package/dist/commands/codex-wake-test.js.map +1 -1
- package/dist/commands/codex.js +46 -7
- package/dist/commands/codex.js.map +1 -1
- package/dist/commands/friction-reminder.d.ts +3 -4
- package/dist/commands/friction-reminder.js +42 -9
- package/dist/commands/friction-reminder.js.map +1 -1
- package/dist/commands/inbox-drain.js +9 -2
- package/dist/commands/inbox-drain.js.map +1 -1
- package/dist/commands/inbox-primer-reminder.d.ts +1 -1
- package/dist/commands/inbox-primer-reminder.js +3 -3
- package/dist/commands/inbox-primer-reminder.js.map +1 -1
- package/dist/commands/inbox-watch.d.ts +3 -0
- package/dist/commands/inbox-watch.js +9 -3
- package/dist/commands/inbox-watch.js.map +1 -1
- package/dist/commands/init.js +14 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mechanic-live.d.ts +12 -0
- package/dist/commands/mechanic-live.js +91 -0
- package/dist/commands/mechanic-live.js.map +1 -0
- package/dist/commands/mechanic-manifest.d.ts +16 -0
- package/dist/commands/mechanic-manifest.js +81 -0
- package/dist/commands/mechanic-manifest.js.map +1 -0
- package/dist/commands/mechanic.d.ts +3 -0
- package/dist/commands/mechanic.js +62 -7
- package/dist/commands/mechanic.js.map +1 -1
- package/dist/commands/opencode-relay.js +10 -1
- package/dist/commands/opencode-relay.js.map +1 -1
- package/dist/commands/reminder-types.d.ts +6 -0
- package/dist/commands/status.d.ts +1 -0
- package/dist/commands/status.js +2 -0
- package/dist/commands/status.js.map +1 -1
- package/dist/guard.d.ts +9 -2
- package/dist/guard.js +12 -5
- package/dist/guard.js.map +1 -1
- package/dist/harness.d.ts +6 -0
- package/dist/harness.js +47 -0
- package/dist/harness.js.map +1 -0
- package/dist/hook.js +81 -4
- package/dist/hook.js.map +1 -1
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/dist/mechanic-friction.d.ts +99 -0
- package/dist/mechanic-friction.js +371 -0
- package/dist/mechanic-friction.js.map +1 -0
- package/dist/mechanic-role.d.ts +20 -0
- package/dist/mechanic-role.js +107 -0
- package/dist/mechanic-role.js.map +1 -0
- package/dist/opencode-plugin.bundle.js +49 -15
- package/dist/session-id.d.ts +1 -1
- package/dist/session-id.js +2 -2
- package/dist/session-id.js.map +1 -1
- package/package.json +1 -1
- package/skill/greprag/SKILL.md +1 -1
- package/skill/greprag/docs/inbox-watch.md +3 -0
- package/skill/mechanic/SKILL.md +22 -0
|
@@ -1746,9 +1746,9 @@ function crushMessages(messages, opts) {
|
|
|
1746
1746
|
}
|
|
1747
1747
|
|
|
1748
1748
|
// src/session-id.ts
|
|
1749
|
-
function armMonitorCommand(short, ownerPid, assistant = false) {
|
|
1749
|
+
function armMonitorCommand(short, ownerPid, assistant = false, mechanic = false) {
|
|
1750
1750
|
const owner = ownerPid ? ` --owner-pid ${ownerPid}` : "";
|
|
1751
|
-
const role = assistant ? " --assistant" : "";
|
|
1751
|
+
const role = mechanic ? " --mechanic" : assistant ? " --assistant" : "";
|
|
1752
1752
|
const watch = `greprag inbox watch --session ${short} --json${owner}${role}`;
|
|
1753
1753
|
return `while true; do ${watch}; case $? in 0|64) break;; esac; sleep 1; done`;
|
|
1754
1754
|
}
|
|
@@ -1756,14 +1756,14 @@ function armMonitorCommand(short, ownerPid, assistant = false) {
|
|
|
1756
1756
|
// src/commands/inbox-primer-reminder.ts
|
|
1757
1757
|
function buildInboxPrimer(env) {
|
|
1758
1758
|
const codex = env.platform === "codex";
|
|
1759
|
-
const arm = armMonitorCommand(env.short, env.ownerPid, env.assistant);
|
|
1759
|
+
const arm = armMonitorCommand(env.short, env.ownerPid, env.assistant, env.mechanic);
|
|
1760
1760
|
return [
|
|
1761
1761
|
// LEAD — the forcing function (restored 2026-06-22). ARM is an ALARM, not reference:
|
|
1762
1762
|
// you are unreachable until you do it, and it must be re-done every time the watcher
|
|
1763
1763
|
// drops. It leads the announce and is loud by design — folding it into a buried bullet
|
|
1764
1764
|
// (v5.49.6) softened it into banner-blindness (fix 16a29a8b's failure mode).
|
|
1765
1765
|
codex ? "[\u26A0 CODEX INBOX WATCHER \u2014 Codex cannot reliably self-arm a foreground Monitor every turn. Live push is owned by the GrepRAG Codex startup sidecar; turn hooks only steer at Codex turn/tool/session boundaries.]" : "[\u26A0 ARM YOUR INBOX WATCHER NOW \u2014 you are UNREACHABLE until you do. Peers are live in your mesh trying to coordinate with this session, and the operator can DM you \u2014 but they reach you ONLY while armed. Unarmed, you are invisible and their messages silently pile up. The watcher can DROP ANYTIME (crash / reload / OOM) \u2014 EVERY turn you are flagged unarmed you MUST re-arm, or coordination breaks.]",
|
|
1766
|
-
codex ? "CODEX: Ensure the sidecar is installed/running with `greprag init --codex --tenant-id <handle> --install-watcher` or `greprag codex startup install`.
|
|
1766
|
+
codex ? "CODEX: Ensure the sidecar is installed/running with `greprag init --codex --tenant-id <handle> --install-watcher` or `greprag codex startup install`. On Windows the startup sidecar uses Codex app-server stdio `thread/resume` for the exact target thread, then `turn/start` or `turn/steer`, and keeps the bridge alive until the turn settles. Native app `send_message_to_thread` / `codex_delegation` proved the messaging pattern; `codex exec resume` is diagnostic/history-only. Verify with `greprag codex doctor --wake-test`. If hooks exist but do not fire, open Codex Desktop Settings -> Settings -> Hooks, trust the GrepRAG commands, and start a fresh Codex session. Then drain what is waiting: `greprag inbox`." : `ARM: Monitor is a deferred tool \u2014 \`ToolSearch select:Monitor\`, then call Monitor with persistent:true, timeout_ms:3600000, description:"greprag inbox ${env.short}", command: \`${arm}\`. The \`--session ${env.short}\` is REQUIRED \u2014 a bare \`greprag inbox watch\` writes no pidfile, so the arm-check reads you unarmed forever. NEVER run it bare also because it is a foreground stream and hangs the turn. Then drain what is waiting: \`greprag inbox\`.`,
|
|
1767
1767
|
"",
|
|
1768
1768
|
// The facts + directives — a flat list (no MODEL/RULES scaffolding; the labels were
|
|
1769
1769
|
// human doc-structure, dead weight to an agent). Everything that helps the agent DECIDE
|
|
@@ -1772,7 +1772,7 @@ function buildInboxPrimer(env) {
|
|
|
1772
1772
|
"\u2022 One shared tenant inbox. `greprag inbox` auto-scopes to YOUR session (lines to/from you only); other sessions' private threads stay hidden. `--all` (tenant-wide audit \u2014 every other session's threads) is OPT-IN: run it ONLY when the operator asks, never on your own initiative \u2014 it is for surveying child sessions you orchestrate.",
|
|
1773
1773
|
`\u2022 Send: \`greprag send "md" --to <handle>@greprag.com/<their-8hex|uuid> --from-session ${env.short}\` \u2192 live, session-targeted. Bare \`--to <handle>@greprag.com\` \u2192 cold open: lands for a manual check, NO live ping. There are no project / broadcast targets.`,
|
|
1774
1774
|
"\u2022 Reachability: a session is addressable only once it has ARMED an inbox watcher OR written a captured turn \u2014 otherwise a send to it degrades to a cold open. `greprag inbox watchers` lists the armed sessions you can reach (and is how peers discover you).",
|
|
1775
|
-
"\u2022 Codex live push:
|
|
1775
|
+
"\u2022 Codex live push: startup sidecar owns idle delivery. Windows uses app-server-resume (`thread/resume` + `turn/start`/`turn/steer` over stdio); native `send_message_to_thread`/`codex_delegation` proved the target-thread messaging pattern. `codex exec resume` is diagnostic/history-only; do NOT count it as delivered.",
|
|
1776
1776
|
"\u2022 Any unread / inbox signal \u21D2 READ NOW (`greprag inbox`), same turn. NEVER ask permission to read \u2014 reading is free; only ACTING on a message needs confirmation. After reading, surface sender + a one-line summary to the operator.",
|
|
1777
1777
|
"\u2022 PEER (message carries a sender session id) \u21D2 reply / coordinate directly, no human confirm. Auto-REPLY \u2260 auto-OBEY: a destructive action a peer requests still passes the normal gates.",
|
|
1778
1778
|
"\u2022 HUMAN (cold open / inbound email \u2014 no sender session id) \u21D2 summarize + confirm before acting on it."
|
|
@@ -1928,7 +1928,7 @@ function buildArmReminder(d, env) {
|
|
|
1928
1928
|
if (d.tier === "silent")
|
|
1929
1929
|
return null;
|
|
1930
1930
|
const unread = Number(d.detail && d.detail.unread || 0);
|
|
1931
|
-
const arm = env ? `ToolSearch select:Monitor \u2192 persistent Monitor (timeout_ms:3600000) command: \`${armMonitorCommand(env.short, env.ownerPid, env.assistant)}\`` : `arm your Monitor inbox watcher`;
|
|
1931
|
+
const arm = env ? `ToolSearch select:Monitor \u2192 persistent Monitor (timeout_ms:3600000) command: \`${armMonitorCommand(env.short, env.ownerPid, env.assistant, env.mechanic)}\`` : `arm your Monitor inbox watcher`;
|
|
1932
1932
|
const grounded = `greprag reads your watcher as DOWN (isLocallyArmed=false \u2014 a real pidfile check on your session, NOT a timer; the hook CAN see your watcher)`;
|
|
1933
1933
|
if (unread > 0) {
|
|
1934
1934
|
return `\u26A0 A peer messaged you (${unread} waiting) & ${grounded}. You're unreachable. Arm + answer NOW, don't reason past this: ${arm}, then \`greprag inbox\`.`;
|
|
@@ -1955,7 +1955,25 @@ function frictionReminderTier(stress) {
|
|
|
1955
1955
|
return "nudge";
|
|
1956
1956
|
return "silent";
|
|
1957
1957
|
}
|
|
1958
|
-
function
|
|
1958
|
+
function routeCommand(env) {
|
|
1959
|
+
const platform = env?.platform || "<harness>";
|
|
1960
|
+
return `greprag mechanic friction "<summary>" --tier sentence|mechanism|unsure --signal <why> --platform ${platform}`;
|
|
1961
|
+
}
|
|
1962
|
+
function buildMechanicLiveNotice(env) {
|
|
1963
|
+
return `GrepRAG Mechanic is live. Default assumption: this working session is NOT the Mechanic; route future friction with \`${routeCommand(env)}\`, then keep working. Check role only when needed: \`greprag mechanic role\`.`;
|
|
1964
|
+
}
|
|
1965
|
+
function buildFrictionReminder(tier, env) {
|
|
1966
|
+
const routed = !!env?.mechanicLive && !env?.mechanic;
|
|
1967
|
+
if (routed) {
|
|
1968
|
+
switch (tier) {
|
|
1969
|
+
case "nag":
|
|
1970
|
+
return `\u26A0 FRICTION HIGH (live signal: repetition / errors / churn) \u2014 a live Mechanic exists, so this stress signal is being auto-forwarded. Add specifics if useful: \`${routeCommand(env)}\`; otherwise keep working.`;
|
|
1971
|
+
case "nudge":
|
|
1972
|
+
return `\u26A0 Friction detected (live signal) \u2014 a live Mechanic exists, so this stress signal is being auto-forwarded. Add specifics if useful: \`${routeCommand(env)}\`; otherwise keep working.`;
|
|
1973
|
+
default:
|
|
1974
|
+
return null;
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1959
1977
|
switch (tier) {
|
|
1960
1978
|
case "nag":
|
|
1961
1979
|
return '\u26A0 FRICTION HIGH (live signal: repetition / errors / churn) \u2014 STOP pushing through; fix the PATTERN now \u2192 `greprag load reflex-chip` (sentence-tier) or `greprag load workshop-chip` (machinery), then spawn_task. No friction? say "clear" + continue.';
|
|
@@ -1970,10 +1988,11 @@ var WORKSHOP_METHOD = "spawn a workshop chip \u2014 `greprag load workshop-chip`
|
|
|
1970
1988
|
function buildMechanicAnnounce() {
|
|
1971
1989
|
return [
|
|
1972
1990
|
"[Active Mechanic \u2014 keep the harness healthy IN-SESSION. Friction is a signal to fix NOW, not to defer; the moment that produced it still holds the context the fix needs.]",
|
|
1973
|
-
"
|
|
1974
|
-
|
|
1975
|
-
`
|
|
1976
|
-
|
|
1991
|
+
"DEFAULT POSTURE: assume this session is NOT the Mechanic. The exception is explicit role signal: `greprag mechanic role` says `current: ... (will arm with --mechanic)` or the hook names this session as mechanic.",
|
|
1992
|
+
'WHEN friction happens in a normal working session \u2014 repeated yourself, fought a tool, got corrected >=2x on the same thing, or rediscovered something already known \u2014 send `greprag mechanic friction "<summary>" --tier sentence|mechanism|unsure --signal <why> --platform <harness>` and keep working. The stress hook auto-forwards broad repetition/error/churn.',
|
|
1993
|
+
`WHEN this session IS the Mechanic: fix the PATTERN now; do not push through. SENTENCE-TIER friction (words in a file you own \u2014 a skill / doc / CLAUDE.md): ${REFLEX_METHOD}. The chip is preloaded with the mechanic tools + live \`greprag mechanic status\`, lands a Tier-0 born-shadow repair, and ends \u2014 no gate to wait at.`,
|
|
1994
|
+
`MECHANISM-TIER friction for the Mechanic (a hook / gate / trigger / code, anything you can't fix in words): ${WORKSHOP_METHOD}.`,
|
|
1995
|
+
'MODES (when unsure which, or when it is not a chip): route (`greprag mechanic friction ...`) \xB7 fix (Mechanic or local blocking repair) \xB7 log (`greprag fix log "<obs>"` to queue it for /mechanic) \xB7 ask-human (the operator must decide).',
|
|
1977
1996
|
"Every repair is ROOT-CAUSE \u2014 fix the pattern that makes the friction class possible, never a guard on today's trigger.",
|
|
1978
1997
|
'A per-turn reminder fires ONLY when live friction is DETECTED (the stress signal \u2014 repetition / errors / churn), never on a timer \u2014 act on it, or say "clear" and continue.'
|
|
1979
1998
|
].join("\n");
|
|
@@ -1981,10 +2000,25 @@ function buildMechanicAnnounce() {
|
|
|
1981
2000
|
var mechanicFrictionModule = {
|
|
1982
2001
|
id: "mechanic-friction",
|
|
1983
2002
|
dependsOn: ["chip-spawn-pointer"],
|
|
1984
|
-
//
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
2003
|
+
// Stress fires the real friction reminder. A designated Mechanic also creates a
|
|
2004
|
+
// one-shot ambient route notice per source session/role epoch (hook-stamped).
|
|
2005
|
+
detect: (env) => {
|
|
2006
|
+
const tier = frictionReminderTier(env.stress);
|
|
2007
|
+
if (tier !== "silent")
|
|
2008
|
+
return { tier };
|
|
2009
|
+
if (env.mechanicLiveNotice && !env.mechanic)
|
|
2010
|
+
return { tier: "ambient" };
|
|
2011
|
+
return { tier: "silent" };
|
|
2012
|
+
},
|
|
2013
|
+
announce: (env = {}) => {
|
|
2014
|
+
const base = buildMechanicAnnounce();
|
|
2015
|
+
if (env.mechanicLive && !env.mechanic)
|
|
2016
|
+
return `${base}
|
|
2017
|
+
|
|
2018
|
+
${buildMechanicLiveNotice(env)}`;
|
|
2019
|
+
return base;
|
|
2020
|
+
},
|
|
2021
|
+
reminder: (d, env) => d.tier === "ambient" ? buildMechanicLiveNotice(env) : buildFrictionReminder(d.tier, env)
|
|
1988
2022
|
};
|
|
1989
2023
|
|
|
1990
2024
|
// src/commands/coordinate-gate.ts
|
package/dist/session-id.d.ts
CHANGED
|
@@ -79,7 +79,7 @@ export declare function buildSessionIdContext(short: string, alias?: string | nu
|
|
|
79
79
|
* made the wrapper unsafe before. The layers: this loop relaunches a dead
|
|
80
80
|
* SUPERVISOR; the supervisor respawns a dead SSE CHILD; EPIPE-terminal stops
|
|
81
81
|
* everything when the consumer leaves. adr: adr/monitor-resilience.md */
|
|
82
|
-
export declare function armMonitorCommand(short: string, ownerPid?: number | null, assistant?: boolean): string;
|
|
82
|
+
export declare function armMonitorCommand(short: string, ownerPid?: number | null, assistant?: boolean, mechanic?: boolean): string;
|
|
83
83
|
/** Handle `greprag-hook session-id`. Reads the Claude Code hook payload
|
|
84
84
|
* from `input.session_id`, emits a JSON response with hookSpecificOutput.
|
|
85
85
|
* additionalContext to stdout. Silent on missing session_id (other hook
|
package/dist/session-id.js
CHANGED
|
@@ -161,14 +161,14 @@ function buildSessionIdContext(short, alias = null) {
|
|
|
161
161
|
* made the wrapper unsafe before. The layers: this loop relaunches a dead
|
|
162
162
|
* SUPERVISOR; the supervisor respawns a dead SSE CHILD; EPIPE-terminal stops
|
|
163
163
|
* everything when the consumer leaves. adr: adr/monitor-resilience.md */
|
|
164
|
-
function armMonitorCommand(short, ownerPid, assistant = false) {
|
|
164
|
+
function armMonitorCommand(short, ownerPid, assistant = false, mechanic = false) {
|
|
165
165
|
// --owner-pid is stamped for audit continuity only; the count-cap never reads it.
|
|
166
166
|
const owner = ownerPid ? ` --owner-pid ${ownerPid}` : '';
|
|
167
167
|
// --assistant elevates the watcher to the tenant's Assistant subscription
|
|
168
168
|
// (session ∪ inbound-email arrivals) — added ONLY for the designated assistant
|
|
169
169
|
// project (isAssistantProject), so a normal session arms a stock watcher.
|
|
170
170
|
// adr: adr/assistant-role.md
|
|
171
|
-
const role = assistant ? ' --assistant' : '';
|
|
171
|
+
const role = mechanic ? ' --mechanic' : (assistant ? ' --assistant' : '');
|
|
172
172
|
const watch = `greprag inbox watch --session ${short} --json${owner}${role}`;
|
|
173
173
|
// Break on 0 (consumer-gone / clean / signal) and 64 (FATAL: bad key) — both are
|
|
174
174
|
// intentional terminals; relaunch on any other code (a crash). `sleep 1` floors
|
package/dist/session-id.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-id.js","sourceRoot":"","sources":["../src/session-id.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcH,8CAKC;AAWD,wCAQC;AAaD,oCAIC;AASD,8CAaC;AAWD,sDAUC;AAuBD,
|
|
1
|
+
{"version":3,"file":"session-id.js","sourceRoot":"","sources":["../src/session-id.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/skill/greprag/SKILL.md
CHANGED
|
@@ -127,7 +127,7 @@ Aliases (silent back-compat): `greprag memory briefing` → `recap` (renamed v5.
|
|
|
127
127
|
|
|
128
128
|
**Codex: DO NOT CLAIM HOOKS ARE ACTIVE JUST BECAUSE `~/.codex/hooks.json` EXISTS.** Codex Desktop requires Settings -> Settings -> Hooks trust review before command hooks run automatically. If turn capture is missing after `greprag init --codex`, tell the user: open Codex Desktop Settings -> Settings -> Hooks, trust the 6 GrepRAG hooks, then start a fresh Codex session.
|
|
129
129
|
|
|
130
|
-
**Codex live inbox push requires the startup watcher plus
|
|
130
|
+
**Codex live inbox push requires the startup watcher plus target-thread delivery.** Hooks only fire at Codex turn/tool/session boundaries. Public installs should use `greprag init --codex --tenant-id <handle> --install-watcher`; run `greprag codex doctor --wake-test` to inspect state, and use `greprag codex watch --session <id>` only for foreground testing. The sidecar listens to GrepRAG inbox SSE. Native `send_message_to_thread` / `codex_delegation` proved the messaging pattern; on Windows the public sidecar uses Codex app-server stdio `thread/resume` for the exact target thread, then `turn/start` or `turn/steer`, and keeps the bridge alive until the turn settles. `codex exec resume` is diagnostic/history-only because it can append to history without surfacing in the active Desktop pane. If wake-test reports no app-server-resume path, describe live push as unavailable/non-visible and rely on turn-bound inbox steering for reliable delivery.
|
|
131
131
|
|
|
132
132
|
**ABOUT TO `greprag send` TO A `@gmail.com` / `@anthropic.com` / REAL EMAIL ADDRESS? STOP — for `inbox`/`send` (internal cross-session messaging), `users.email` IS NEVER A ROUTING ADDRESS.** Use the numeric handle (`1834729@greprag.com`) or claimed vanity alias (`travis@greprag.com`). If you don't know the recipient's handle, ASK — don't guess from their email. adr: adr/numeric-handles.md. Full grammar: `docs/inbox.md § address`.
|
|
133
133
|
|
|
@@ -9,12 +9,15 @@ greprag inbox watch # tenant-wide stream
|
|
|
9
9
|
greprag inbox watch --project <name> # only messages addressed to this project
|
|
10
10
|
greprag inbox watch --session <id> # only messages targeting this session (strictest)
|
|
11
11
|
greprag inbox watch --receptionist # also wake on the front desk (cold opens + email)
|
|
12
|
+
greprag inbox watch --mechanic # also wake on live mechanic_friction events
|
|
12
13
|
greprag inbox watch --since <id-or-iso> # resume from a known cursor
|
|
13
14
|
greprag inbox watch --json # one JSON object per line (preferred under Monitor)
|
|
14
15
|
```
|
|
15
16
|
|
|
16
17
|
`--project` and `--session` compose. `--session` is the strictest filter: only messages with matching `to_session_id` get through. The tenant catch-all (cold open / inbound email — `to_session_id IS NULL`) does NOT reach a session- or project-scoped watcher; only a `--receptionist` watcher wakes on it (Option C). adr: adr/address-grammar.md. This eliminates cross-session noise when several Claude sessions watch the same project's inbox at once.
|
|
17
18
|
|
|
19
|
+
`--mechanic` is a role subscription: it keeps the normal session/project lane and adds only tenant `mechanic_friction` events. It does not wake on ordinary cold opens or inbound email.
|
|
20
|
+
|
|
18
21
|
Each message arrives within ~500ms of the sender's `greprag send` (210ms verified end-to-end). Connection auto-reconnects with exponential backoff; the watcher tracks last seen message id and uses it as `since=` on reconnect — nothing dropped, nothing duplicated.
|
|
19
22
|
|
|
20
23
|
## Liveness model (post v0.8.5)
|
package/skill/mechanic/SKILL.md
CHANGED
|
@@ -59,6 +59,7 @@ Same gate the hourly compactor applies at write-time — Mechanic and compactor
|
|
|
59
59
|
- **Bulk is fine for Tier-0 when the set is named aloud** (clearing verified-stale / noise fixes); never bulk a Tier-2 action.
|
|
60
60
|
- **Never edit `~/.claude/docs/chip-spawn.md` without confirm.** Global rules are sticky.
|
|
61
61
|
- **Cross-project carve-out.** Default to the current project (resolved via `greprag fix list`). The Phase 0 census MAY read sibling queues to show where fixes piled up; *draining* one requires the operator to name it, and every `add`/`delete` against it MUST carry `--project <that-project>`. Never touch a sibling silently.
|
|
62
|
+
- **Harness scope is mandatory.** Friction carries its source harness (`claude-code`, `codex`, `opencode`). Repairs to hooks/skills/watchers must target that harness with `greprag mechanic install ... --harness <name>`. In a Codex session, default to `--harness codex`; use `--harness all` only for deliberately portable mechanisms.
|
|
62
63
|
|
|
63
64
|
## Phase 0 — Fix digestion
|
|
64
65
|
|
|
@@ -200,6 +201,14 @@ Append `(phase <X> skipped)` per skipped phase.
|
|
|
200
201
|
Repairs (D3 rows attached to fixes) are managed with `greprag mechanic`, not by editing hooks:
|
|
201
202
|
|
|
202
203
|
```
|
|
204
|
+
greprag mechanic set mark THIS project/session as the live Mechanic role;
|
|
205
|
+
fan out `mechanic_live` to open sessions;
|
|
206
|
+
arm with --mechanic to receive live friction
|
|
207
|
+
greprag mechanic role show whether this project is the live Mechanic
|
|
208
|
+
greprag mechanic friction "obs" explicit live friction brief; hook stress forwarding
|
|
209
|
+
emits the same `mechanic_friction` message type
|
|
210
|
+
greprag mechanic reply --to <8hex> typed follow-up from Mechanic to source session;
|
|
211
|
+
"msg" [--friction-id <id>] do not use generic send for mechanic workflow
|
|
203
212
|
greprag mechanic status inventory: live (shadow|active) repairs grouped by status,
|
|
204
213
|
each with a verdict (working|failed|harmful|unproven|dormant);
|
|
205
214
|
⚑ marks shadow rows ready to graduate (≥3 fires or ≥7 days)
|
|
@@ -210,6 +219,19 @@ greprag mechanic why <nodeId> provenance: the friction → fix → repai
|
|
|
210
219
|
greprag mechanic off / on PANIC SWITCH — local file, no network; suspends ALL repairs
|
|
211
220
|
```
|
|
212
221
|
|
|
222
|
+
**Live Mechanic role.** A `--mechanic` inbox watcher receives tenant
|
|
223
|
+
`mechanic_friction` events in addition to its own session lane. Working sessions
|
|
224
|
+
always assume they are not the Mechanic unless `greprag mechanic role` says the
|
|
225
|
+
current session will arm with `--mechanic`. `greprag mechanic set` sends an
|
|
226
|
+
immediate typed `mechanic_live` notice to currently open same-project sessions;
|
|
227
|
+
SessionStart and the reminder hook cover sessions that launch or turn later.
|
|
228
|
+
Working sessions emit friction automatically when the stress detector fires, and
|
|
229
|
+
manually via `greprag mechanic friction "..." --tier sentence|mechanism|unsure
|
|
230
|
+
--signal <why> --platform <harness>`, then keep working unless blocked. The event
|
|
231
|
+
is internal queue/work mail: it does not wake ordinary sessions or Assistant. The
|
|
232
|
+
Mechanic replies with `greprag mechanic reply --to <source-session> "..."` for
|
|
233
|
+
coordination and pings the operator for status/Tier-2 gates.
|
|
234
|
+
|
|
213
235
|
**Born shadow → graduate.** Every repair is born `shadow`: it matches and logs would-have-fired
|
|
214
236
|
evidence but injects nothing. Graduation is evidence-first — when `status` flags a row `⚑`, review
|
|
215
237
|
its fire history (`why`) and `enable` it. Nothing goes live without the operator; the gates are
|