tickmarkr 2.1.6 → 2.1.8
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/cli/commands/beat.js +37 -10
- package/dist/cli/commands/doctor.d.ts +3 -0
- package/dist/cli/commands/doctor.js +23 -1
- package/dist/cli/commands/plan.d.ts +6 -2
- package/dist/cli/commands/plan.js +94 -1
- package/dist/cli/commands/run.js +21 -2
- package/dist/cli/commands/stats.js +4 -14
- package/dist/cli/commands/status.js +73 -26
- package/dist/compile/index.d.ts +1 -1
- package/dist/compile/index.js +24 -5
- package/dist/compile/native.js +14 -0
- package/dist/compile/ownership.d.ts +35 -0
- package/dist/compile/ownership.js +213 -0
- package/dist/drivers/herdr.d.ts +1 -0
- package/dist/drivers/herdr.js +7 -6
- package/dist/drivers/types.d.ts +2 -0
- package/dist/drivers/types.js +54 -14
- package/dist/gates/acceptance.d.ts +13 -0
- package/dist/gates/acceptance.js +43 -16
- package/dist/gates/baseline.js +12 -1
- package/dist/gates/run-gates.js +26 -23
- package/dist/run/daemon.js +42 -7
- package/dist/run/journal.js +21 -1
- package/dist/run/outcome.js +8 -1
- package/dist/run/supervision.d.ts +15 -1
- package/dist/run/supervision.js +112 -14
- package/package.json +1 -1
- package/skills/tickmarkr-auto/SKILL.md +2 -1
- package/skills/tickmarkr-loop/SKILL.md +2 -1
- package/skills/tickmarkr-overseer/SKILL.md +9 -0
- package/skills/tickmarkr-overseer/scripts/watch-context.sh +46 -32
|
@@ -20,15 +20,15 @@
|
|
|
20
20
|
# than absent. Four rules the shipped version broke, each of which made the tier lie:
|
|
21
21
|
# 1. BEAT ON THE SUPERVISION CADENCE, NOT ON THE POLL. Beats gap by TICK (below), never by POLL, so a
|
|
22
22
|
# poll interval above the supervision beat interval cannot leave the tier stale half of every cycle.
|
|
23
|
-
# 2. BEAT
|
|
24
|
-
#
|
|
23
|
+
# 2. BEAT AFTER EVERY SUCCESSFUL SCREEN READ. A missing percentage is an explicit UNREADABLE
|
|
24
|
+
# observation: it must keep the live watcher armed but can never reach warn or act. Only a failed
|
|
25
|
+
# screen read withholds the beat, because then the watcher cannot see its seat at all.
|
|
25
26
|
# 3. WARN DOES NOT EXIT. Warn precedes act, so exiting at warn meant the act was never reached and the
|
|
26
27
|
# last beat aged into a permanent stale — gradual growth never reached the auto-clear path at all.
|
|
27
28
|
# 4. EVERY TERMINAL EXIT STANDS THE TIER DOWN, so a watcher that finished reads DISARMED, not dead.
|
|
28
29
|
# Only a killed watcher reads STALE, which is exactly what STALE means.
|
|
29
|
-
# 5.
|
|
30
|
-
#
|
|
31
|
-
# must never look alike.
|
|
30
|
+
# 5. AN UNREADABLE FIELD REPORTS ITSELF (OBS-739/780). Silence, health and a trustworthy percentage
|
|
31
|
+
# are three different states. UNREADABLE stays supervised but never authorises a destructive act.
|
|
32
32
|
#
|
|
33
33
|
# usage: watch-context.sh <role-slug> <agent|pane> <warn-pct> <act-pct> [handoff-file] [poll-s] [cap-s]
|
|
34
34
|
# <role-slug> is ANY seat role — orchestrator, overseer, surgeon, consult — and names the tier
|
|
@@ -63,8 +63,8 @@ TIER="${ROLE}-context"
|
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
# The supervision beat interval (SUPERVISION_BEAT_MS = 10s). The loop ticks at the beat cadence or the
|
|
66
|
-
# caller's poll, whichever is SHORTER
|
|
67
|
-
#
|
|
66
|
+
# caller's poll, whichever is SHORTER. Every successful screen read beats; its result is either a
|
|
67
|
+
# percentage safe to compare or the explicit UNREADABLE state.
|
|
68
68
|
BEAT_EVERY=5
|
|
69
69
|
TICK=$(( POLL < BEAT_EVERY ? POLL : BEAT_EVERY ))
|
|
70
70
|
[ "$TICK" -ge 1 ] 2>/dev/null || TICK=1 # a zero or junk poll would spin, not watch
|
|
@@ -100,16 +100,18 @@ stand_down() { tickmarkr beat "$TIER" --stand-down --seat "$SEAT" >/dev/null 2>&
|
|
|
100
100
|
# record the hand-off. A killed watcher never runs it, which is the one case that must read STALE.
|
|
101
101
|
trap stand_down EXIT
|
|
102
102
|
|
|
103
|
-
# The seat's
|
|
104
|
-
#
|
|
105
|
-
#
|
|
106
|
-
# its cap while its tier claimed coverage. The last percentage in the statusline window is the fallback.
|
|
103
|
+
# The seat's rendered truth lives on the model banner. Select that line first, then read a percentage
|
|
104
|
+
# only from it: a bare numeric search across the visible window can borrow an old N% from scrollback
|
|
105
|
+
# when a long live-run segment pushes the real field past the pane's visible width (OBS-780).
|
|
107
106
|
context_pct() {
|
|
108
|
-
local screen
|
|
107
|
+
local screen banner pct
|
|
109
108
|
screen=$(herdr agent read "$TARGET" --source visible --lines 8 2>/dev/null) || return 1
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
banner=$(printf '%s\n' "$screen" |
|
|
110
|
+
grep -Ei '(^|[^[:alnum:]])(claude|opus|sonnet|haiku|gpt|gemini|glm|kimi|grok|composer|openai|zai)[[:alnum:]_./-]*([[:space:]]|$)' |
|
|
111
|
+
tail -1)
|
|
112
|
+
[ -n "$banner" ] || { printf 'UNREADABLE\n'; return 0; }
|
|
113
|
+
pct=$(printf '%s\n' "$banner" | grep -oE '[0-9]+%' | tail -1 | tr -d '%')
|
|
114
|
+
[ -n "$pct" ] && printf '%s\n' "$pct" || printf 'UNREADABLE\n'
|
|
113
115
|
}
|
|
114
116
|
|
|
115
117
|
handoff_fresh() {
|
|
@@ -144,35 +146,47 @@ act_on() {
|
|
|
144
146
|
|
|
145
147
|
warned=0
|
|
146
148
|
elapsed=0
|
|
147
|
-
blind=0 # seconds in the current
|
|
149
|
+
blind=0 # seconds in the current failed-read spell (OBS-739)
|
|
148
150
|
blind_alarmed=0
|
|
151
|
+
unreadable_reported=0
|
|
149
152
|
BLIND_ALARM_S="${TKR_BLIND_ALARM_S:-120}"
|
|
150
153
|
while [ "$elapsed" -lt "$CAP" ]; do
|
|
151
|
-
P=$(context_pct)
|
|
154
|
+
if ! P=$(context_pct); then P=""; fi
|
|
152
155
|
if [ -z "$P" ]; then
|
|
153
|
-
#
|
|
154
|
-
#
|
|
155
|
-
|
|
156
|
-
# Rule 5 (OBS-739): ALARM ON THE BLIND READ. Ageing a tier is not enough — it is only visible to
|
|
157
|
-
# someone already reading the beat table, and the measured failure was a watcher ALIVE AND BLIND for
|
|
158
|
-
# hours because the run's own status text pushed the percentage off the statusline. An instrument
|
|
159
|
-
# that cannot report its own absence is worse than none: the seat believes it has coverage and stops
|
|
160
|
-
# looking. So say so on stdout, where the supervising seat is actually woken. Once per blind spell,
|
|
161
|
-
# not every tick — a repeating alarm trains the reader to ignore it.
|
|
156
|
+
# The screen read itself failed: no observation, no beat. The tier ages to STALE and the watcher
|
|
157
|
+
# alarms once, because an instrument that cannot see its seat must never look healthy.
|
|
158
|
+
unreadable_reported=0
|
|
162
159
|
blind=$((blind + TICK))
|
|
163
160
|
if [ "$blind" -ge "$BLIND_ALARM_S" ] && [ "$blind_alarmed" -eq 0 ]; then
|
|
164
161
|
blind_alarmed=1
|
|
165
|
-
echo "CONTEXT_BLIND $TARGET —
|
|
166
|
-
echo " this watcher is NOT providing coverage: read the seat by hand and
|
|
167
|
-
echo " do NOT substitute the token total — '∑ Nk tok' is cumulative SPEND, not context fill"
|
|
162
|
+
echo "CONTEXT_BLIND $TARGET — screen unreadable for ${blind}s; tier ${TIER} is ALIVE AND BLIND"
|
|
163
|
+
echo " this watcher is NOT providing coverage: read the seat by hand and repair the screen read"
|
|
168
164
|
fi
|
|
169
165
|
sleep "$TICK"; elapsed=$((elapsed + TICK)); continue
|
|
170
166
|
fi
|
|
171
|
-
|
|
167
|
+
|
|
168
|
+
if [ "$P" = "UNREADABLE" ]; then
|
|
169
|
+
# The screen read succeeded, so keep the watcher armed. The absent field is still not a number:
|
|
170
|
+
# report it once per spell and never let it flow into warn or act.
|
|
171
|
+
if [ "$blind_alarmed" -eq 1 ]; then
|
|
172
|
+
echo "CONTEXT_BLIND_CLEARED $TARGET — screen readable again after ${blind}s blind"
|
|
173
|
+
fi
|
|
174
|
+
blind=0; blind_alarmed=0
|
|
175
|
+
beat
|
|
176
|
+
if [ "$unreadable_reported" -eq 0 ]; then
|
|
177
|
+
unreadable_reported=1
|
|
178
|
+
echo "CONTEXT_UNREADABLE $TARGET — model banner has no visible percentage; no warn or act authorised"
|
|
179
|
+
fi
|
|
180
|
+
sleep "$TICK"; elapsed=$((elapsed + TICK)); continue
|
|
181
|
+
fi
|
|
182
|
+
|
|
183
|
+
if [ "$unreadable_reported" -eq 1 ]; then
|
|
184
|
+
echo "CONTEXT_UNREADABLE_CLEARED $TARGET — percentage readable again at ${P}%"
|
|
185
|
+
fi
|
|
172
186
|
if [ "$blind_alarmed" -eq 1 ]; then
|
|
173
187
|
echo "CONTEXT_BLIND_CLEARED $TARGET — percentage readable again at ${P}% after ${blind}s blind"
|
|
174
188
|
fi
|
|
175
|
-
blind=0; blind_alarmed=0
|
|
189
|
+
blind=0; blind_alarmed=0; unreadable_reported=0
|
|
176
190
|
beat
|
|
177
191
|
|
|
178
192
|
if [ "$P" -ge "$ACT" ] 2>/dev/null; then
|
|
@@ -190,4 +204,4 @@ while [ "$elapsed" -lt "$CAP" ]; do
|
|
|
190
204
|
sleep "$TICK"; elapsed=$((elapsed + TICK))
|
|
191
205
|
done
|
|
192
206
|
|
|
193
|
-
echo "WATCH_CAP_REACHED $TARGET
|
|
207
|
+
echo "WATCH_CAP_REACHED $TARGET — no threshold crossed in ${CAP}s"
|