greprag 5.52.0 → 5.53.1
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/commands/arm-reminder.js +1 -1
- package/dist/commands/arm-reminder.js.map +1 -1
- package/dist/commands/codex-supervisor.js +27 -8
- package/dist/commands/codex-supervisor.js.map +1 -1
- package/dist/commands/codex.js +27 -4
- package/dist/commands/codex.js.map +1 -1
- package/dist/commands/docptr.js +16 -3
- package/dist/commands/docptr.js.map +1 -1
- package/dist/commands/email-primer-reminder.d.ts +23 -0
- package/dist/commands/email-primer-reminder.js +38 -0
- package/dist/commands/email-primer-reminder.js.map +1 -0
- 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 -4
- 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/mechanic-live.d.ts +12 -0
- package/dist/commands/mechanic-live.js +89 -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 +61 -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-registry.js +2 -0
- package/dist/commands/reminder-registry.js.map +1 -1
- package/dist/commands/reminder-types.d.ts +6 -0
- package/dist/docptr-refs.d.ts +37 -0
- package/dist/docptr-refs.js +148 -0
- package/dist/docptr-refs.js.map +1 -0
- 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 +110 -10
- 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 +93 -0
- package/dist/mechanic-friction.js +368 -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 +69 -17
- 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/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,7 +1756,7 @@ 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
|
|
@@ -1769,14 +1769,13 @@ function buildInboxPrimer(env) {
|
|
|
1769
1769
|
// human doc-structure, dead weight to an agent). Everything that helps the agent DECIDE
|
|
1770
1770
|
// (address grammar, reachability, peer vs human) and ACT (read-now, front-desk).
|
|
1771
1771
|
"[greprag inbox \u2014 how it works + what to do:]",
|
|
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)
|
|
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
|
|
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
|
+
`\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
1775
|
"\u2022 Codex live push: Desktop-visible wake requires app-layer thread continuation (`send_message_to_thread` shape, visible `codex_delegation` turn). `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
|
-
"\u2022 HUMAN (cold open / inbound email \u2014 no sender session id) \u21D2 summarize + confirm before acting on it."
|
|
1779
|
-
"\u2022 Front desk = the operator's shared mailbox (cold opens + inbound email), NOT yours. OPT-IN ONLY: never read it on your own initiative and you are never auto-notified of it \u2014 open `greprag inbox --front-desk` ONLY when the operator explicitly asks you to check the front desk. Do NOT auto-drain it (reading marks-read and consumes the operator's cold opens before a receptionist sees them)."
|
|
1778
|
+
"\u2022 HUMAN (cold open / inbound email \u2014 no sender session id) \u21D2 summarize + confirm before acting on it."
|
|
1780
1779
|
].join("\n");
|
|
1781
1780
|
}
|
|
1782
1781
|
var inboxPrimerModule = {
|
|
@@ -1813,6 +1812,23 @@ var chipSpawnPointerModule = {
|
|
|
1813
1812
|
reminder: () => null
|
|
1814
1813
|
};
|
|
1815
1814
|
|
|
1815
|
+
// src/commands/email-primer-reminder.ts
|
|
1816
|
+
var EMAIL_PRIMER = [
|
|
1817
|
+
"[greprag email \u2014 the agent's REAL mailbox (actual inbound + outbound SMTP), distinct from `greprag send` (internal session mesh, never real email).]",
|
|
1818
|
+
'\u2022 SEND real mail: `greprag email send --to <addr> --subject "s" (--body "t" | --body-file <f|->)` \u2014 from your <handle>@greprag.com. Flags: --html-file (rich body) \xB7 --attach (repeatable) \xB7 --cc/--bcc \xB7 --reply-to \xB7 --from-name \xB7 --from <your-own-handle> (server rejects any address that isn\'t yours \u2014 no forging).',
|
|
1819
|
+
"\u2022 INBOUND + attachments: `greprag email` / `email pending` list inbound mail; `email pull` drains attachments to disk. Scope one mailbox with `--box <addr|domain|default>`.",
|
|
1820
|
+
"\u2022 Boxes + domains: `greprag email boxes` (your mailboxes + pending counts) \xB7 `greprag email domains` (custom sending domains \u2014 `domain add|verify|name|remove`)."
|
|
1821
|
+
].join("\n");
|
|
1822
|
+
var emailPrimerModule = {
|
|
1823
|
+
id: "email-primer",
|
|
1824
|
+
// Contrasts `email send` with the inbox primer's `send` → inbox-primer must land first.
|
|
1825
|
+
dependsOn: ["inbox-primer"],
|
|
1826
|
+
detect: (_env) => ({ tier: "silent" }),
|
|
1827
|
+
// never a per-turn nag
|
|
1828
|
+
announce: (_env) => EMAIL_PRIMER,
|
|
1829
|
+
reminder: () => null
|
|
1830
|
+
};
|
|
1831
|
+
|
|
1816
1832
|
// src/commands/corpus-reminder.ts
|
|
1817
1833
|
function buildCorpusAnnounce(names) {
|
|
1818
1834
|
if (!names || names.length === 0)
|
|
@@ -1912,7 +1928,7 @@ function buildArmReminder(d, env) {
|
|
|
1912
1928
|
if (d.tier === "silent")
|
|
1913
1929
|
return null;
|
|
1914
1930
|
const unread = Number(d.detail && d.detail.unread || 0);
|
|
1915
|
-
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`;
|
|
1916
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)`;
|
|
1917
1933
|
if (unread > 0) {
|
|
1918
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\`.`;
|
|
@@ -1939,7 +1955,25 @@ function frictionReminderTier(stress) {
|
|
|
1939
1955
|
return "nudge";
|
|
1940
1956
|
return "silent";
|
|
1941
1957
|
}
|
|
1942
|
-
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
|
+
}
|
|
1943
1977
|
switch (tier) {
|
|
1944
1978
|
case "nag":
|
|
1945
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.';
|
|
@@ -1954,10 +1988,11 @@ var WORKSHOP_METHOD = "spawn a workshop chip \u2014 `greprag load workshop-chip`
|
|
|
1954
1988
|
function buildMechanicAnnounce() {
|
|
1955
1989
|
return [
|
|
1956
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.]",
|
|
1957
|
-
"
|
|
1958
|
-
|
|
1959
|
-
`
|
|
1960
|
-
|
|
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).',
|
|
1961
1996
|
"Every repair is ROOT-CAUSE \u2014 fix the pattern that makes the friction class possible, never a guard on today's trigger.",
|
|
1962
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.'
|
|
1963
1998
|
].join("\n");
|
|
@@ -1965,10 +2000,25 @@ function buildMechanicAnnounce() {
|
|
|
1965
2000
|
var mechanicFrictionModule = {
|
|
1966
2001
|
id: "mechanic-friction",
|
|
1967
2002
|
dependsOn: ["chip-spawn-pointer"],
|
|
1968
|
-
//
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
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)
|
|
1972
2022
|
};
|
|
1973
2023
|
|
|
1974
2024
|
// src/commands/coordinate-gate.ts
|
|
@@ -2115,6 +2165,8 @@ var REGISTRY = [
|
|
|
2115
2165
|
inboxPrimerModule,
|
|
2116
2166
|
loadPrimerModule,
|
|
2117
2167
|
chipSpawnPointerModule,
|
|
2168
|
+
emailPrimerModule,
|
|
2169
|
+
// resident primer: greprag email is a first-class CLI feature (real SMTP), distinct from `send`
|
|
2118
2170
|
corpusAnnounceModule,
|
|
2119
2171
|
docPointerAnnounceModule,
|
|
2120
2172
|
// announce-only "core documents" list (docs/doc-pointer-system.md)
|
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
|
@@ -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
|