fix(6470): a moment proposal counts only opens no hook explained, and asks the reader to judge it
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / TypeScript typecheck (push) Successful in 35s
CI & Build / integration (push) Successful in 1m4s
CI & Build / Python tests (push) Successful in 1m46s
CI & Build / Build & push image (push) Successful in 37s

The signal counted every get_rule open against every moment from the
previous three minutes, so a rule a search arm had just shown was
proposed for whatever moment happened to fire. All nine pending signal
proposals were wrong.

- The hook skips an open of a rule a hook named this session, and sends
  the last three acts from 90 seconds instead of 30 from 180.
- A rule already mounted anywhere gathers no signal evidence.
- A signal pair keeps the actions that reached its moment and shows them
  as its why.
- The proposal line says it is co-occurrence, not a recommendation, and
  asks the reader to check the rule against the moment before offering
  it; moments.md says the same.

Plugin 2026.10.26.2029.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-26 16:29:40 -04:00
co-authored by Claude Opus 5.5
parent 83cb6420e2
commit 7faaa311d7
7 changed files with 178 additions and 30 deletions
+17 -7
View File
@@ -72,19 +72,29 @@ printf '%s\n' "$rule_id" | grimoire_rules_append "$state_dir/${safe_sid}.opened.
# ── What came just before the open ───────────────────────────────────────
#
# grimoire_moment.sh writes every call to `grimoire-moment/<sid>.acts`. The ones
# from the last three minutes go to the server with this rule's id: a rule
# opened just after a moment fired is evidence it belongs on that moment, and
# once that repeats across sessions the server answers with one line asking
# the reader to offer the operator the mount. Nothing is mounted by this.
# grimoire_moment.sh writes every call to `grimoire-moment/<sid>.acts`. The
# last three, from the last ninety seconds, go to the server with this rule's
# id: a rule the agent went and opened right after a moment fired is evidence
# it belongs on that moment, and once that repeats across sessions the server
# answers with one line putting the question to the reader. Nothing is
# mounted by this.
#
# An open of a rule a hook has just NAMED is not reported. A ranked arm or a
# moment line put it in front of the reader, and that explains the open; the
# moment beside it did not, so counting it would propose mounts on whatever
# moment happened to fire while search was surfacing the rule. The window is
# short for the same reason: a few minutes of agent work reaches many moments.
command -v curl >/dev/null 2>&1 || exit 0
grimoire_config || exit 0
case ",$(grimoire_rules_live "$state_dir/${safe_sid}.rules.ids")," in
*",${rule_id},"*) exit 0 ;;
esac
acts_file="${TMPDIR:-/tmp}/grimoire-moment/${safe_sid}.acts"
[ -f "$acts_file" ] || exit 0
now=$(date +%s 2>/dev/null) || exit 0
acts=$(awk -F '\t' -v since=$((now - 180)) \
acts=$(awk -F '\t' -v since=$((now - 90)) \
'$1 + 0 >= since { sub(/^[^\t]*\t/, ""); print }' "$acts_file" 2>/dev/null \
| tail -n 30 | paste -sd ',' - 2>/dev/null)
| tail -n 3 | paste -sd ',' - 2>/dev/null)
[ -n "$acts" ] || exit 0
sid_esc=$(printf '%s' "$session_id" | grimoire_json_escape) || exit 0