@remembrance-ai/opencode-plugin 0.1.73 → 0.1.76
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/README.md +12 -3
- package/opencode.json +2 -2
- package/package.json +1 -1
- package/scripts/hook-core.mjs +707 -41
- package/servers/remembrance-mcp.mjs +646 -60
- package/skills/remembrancer/SKILL.md +32 -12
- package/skills/remembrancer/references/remembrance-setup.md +11 -4
- package/src/index.mjs +50 -11
|
@@ -22,8 +22,8 @@ background and register a privacy-bounded runtime profile. They never transmit
|
|
|
22
22
|
the hostname, username, config path, or repository path. Follow the returned
|
|
23
23
|
machine-readable `next_action` rather than asking the user to invent an
|
|
24
24
|
identity. Tool-observer and completion timestamps appear after those events
|
|
25
|
-
become eligible
|
|
26
|
-
|
|
25
|
+
become eligible. A fresh doctor reports them as informational; only a later
|
|
26
|
+
missed lifecycle opportunity raises an attention warning.
|
|
27
27
|
|
|
28
28
|
If this skill is visible but `run_connection_doctor` is absent, explicitly tell
|
|
29
29
|
the user that Remembrance is only partially active. Do not silently fall back
|
|
@@ -97,6 +97,20 @@ Also use this skill when:
|
|
|
97
97
|
|
|
98
98
|
Do not directly mutate shared skills. Submit structured remembrances, suggestions, or candidate skills for verification.
|
|
99
99
|
|
|
100
|
+
Route memory by audience, not by which write tool is most convenient:
|
|
101
|
+
|
|
102
|
+
- Host-local memory is for facts about this human, repository, installation, or machine.
|
|
103
|
+
- Remembrance is for a generalized lesson another approved organization agent would otherwise rediscover the hard way.
|
|
104
|
+
- A local-memory write does not satisfy organization-shared capture. Generalize reusable feedback and use the private lesson lane; never mirror raw local memory automatically.
|
|
105
|
+
|
|
106
|
+
`get_connection_status` exposes content-free recent contribution outcomes for
|
|
107
|
+
the current installation principal, or for the current API key when an older
|
|
108
|
+
client has no principal. Use it when the user asks whether prior contributions
|
|
109
|
+
were accepted, recognized as duplicates, remain pending, need review, or were
|
|
110
|
+
rejected. It covers remembrances, private skill ideas, skill suggestions,
|
|
111
|
+
resource submissions, and resource reviews. It never returns lesson text,
|
|
112
|
+
titles, rejection prose, actor identity, or private payload data.
|
|
113
|
+
|
|
100
114
|
Do not use this skill when:
|
|
101
115
|
|
|
102
116
|
- The user asks for general web search, research, or current facts.
|
|
@@ -176,8 +190,10 @@ nothing was sent and the encrypted draft remains local in
|
|
|
176
190
|
`awaiting_authorization`; do not retry it through REST or another transport.
|
|
177
191
|
Transient timeouts, 429s, and 5xx responses remain queued for bounded retry on a
|
|
178
192
|
later lifecycle. Authentication, policy, or validation failures remain held.
|
|
179
|
-
|
|
180
|
-
confirmed local action.
|
|
193
|
+
Unresolved and terminal lessons never expire or auto-delete; deleting one
|
|
194
|
+
requires an explicit confirmed local action. After a signed submission receipt
|
|
195
|
+
is verified, the encrypted lesson content is removed immediately and its
|
|
196
|
+
content-free completion marker is automatically deleted after 14 days.
|
|
181
197
|
|
|
182
198
|
The signed policy pins `private-lesson-redaction-v2` and the exact digest of its
|
|
183
199
|
current rules. An unsupported version or digest moves the encrypted draft to
|
|
@@ -188,14 +204,18 @@ terminal count, retained bytes, reason, and explicit deletion guidance without
|
|
|
188
204
|
returning draft content or a local path.
|
|
189
205
|
|
|
190
206
|
The private lesson endpoint derives its organization and private visibility
|
|
191
|
-
from the authenticated key.
|
|
192
|
-
back to public submission. Accepted candidates enter the
|
|
193
|
-
topology, review-policy, encrypted-storage, and audit
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
207
|
+
from the authenticated key. The action always submits privately and never
|
|
208
|
+
falls back to anonymous or public submission. Accepted candidates enter the
|
|
209
|
+
existing verifier, topology, review-policy, encrypted-storage, and audit
|
|
210
|
+
pipelines. After an accepted private outcome, a separate server-owned process
|
|
211
|
+
may create a freshly redacted public candidate only when the organization admin
|
|
212
|
+
enabled **Contribution propagation**; the agent neither chooses nor sees that
|
|
213
|
+
process, and the derivative must pass the complete public pipeline. Rich
|
|
214
|
+
content, raw traces, URLs, code blocks, attachments, secrets, paths,
|
|
215
|
+
identifiers, or ambiguous material stays local and must not be forced through
|
|
216
|
+
by confirmation. Use `inspect_private_lesson_outbox` to inspect content-free
|
|
217
|
+
state, retry a selected draft with `retry_private_lesson_candidate`, and delete
|
|
218
|
+
only with `delete_private_lesson_candidate` plus explicit confirmation.
|
|
199
219
|
|
|
200
220
|
When health reporting is enabled, a held draft may use the same exact submit
|
|
201
221
|
action to send only a `held_safety_event`: event type, held category counts,
|
|
@@ -284,16 +284,23 @@ This is the only host-visible network action in the flow. Approve or persist
|
|
|
284
284
|
approval for this exact action, not every Remembrance write. The server derives
|
|
285
285
|
the organization and private visibility from the authenticated key, verifies a
|
|
286
286
|
signed organization policy plus purpose-bound attestation, and returns a signed
|
|
287
|
-
content-free receipt. The
|
|
288
|
-
public
|
|
287
|
+
content-free receipt. The action always submits privately and never falls back
|
|
288
|
+
to anonymous or public submission. After an accepted private outcome, a
|
|
289
|
+
separate server-owned process may create a freshly redacted public candidate
|
|
290
|
+
only when the organization admin enabled the **Contribution propagation**
|
|
291
|
+
setting; the submitting agent neither chooses nor sees that process, and the
|
|
292
|
+
derivative must pass the complete public pipeline.
|
|
289
293
|
|
|
290
294
|
If the host denies the action, no candidate content was sent. The encrypted
|
|
291
295
|
draft remains on the device in `awaiting_authorization`; do not retry it
|
|
292
296
|
through REST, hosted MCP, or another transport. Timeouts, 429s, and 5xx
|
|
293
297
|
responses retry with bounded backoff during later plugin lifecycles. A 401,
|
|
294
298
|
403, policy change, or validation failure remains held for explicit repair.
|
|
295
|
-
|
|
296
|
-
with the local private-lesson tools; deletion requires
|
|
299
|
+
Unresolved and terminal drafts never expire or auto-delete. Inspect, retry, or
|
|
300
|
+
explicitly delete one with the local private-lesson tools; deletion requires
|
|
301
|
+
confirmation. After a signed submission receipt is verified, the encrypted
|
|
302
|
+
lesson content is removed immediately and its content-free completion marker
|
|
303
|
+
is automatically deleted after 14 days.
|
|
297
304
|
|
|
298
305
|
The signed organization policy pins `private-lesson-redaction-v2` and its exact
|
|
299
306
|
supported redactor digest. If either is unsupported, the finalized
|
package/src/index.mjs
CHANGED
|
@@ -45,21 +45,21 @@ import {
|
|
|
45
45
|
decideStop,
|
|
46
46
|
directSelectionFromResponse,
|
|
47
47
|
highMatchFromResponse,
|
|
48
|
-
markCurrentEngagementHandled,
|
|
49
48
|
markHostPolicyAlertDelivered,
|
|
49
|
+
observeSuccessfulCompletionTool,
|
|
50
50
|
recordDirectiveFollowThroughForTool,
|
|
51
51
|
recordDirectSelectionSurface,
|
|
52
52
|
recordDirectiveSurface,
|
|
53
53
|
recordHighMatchSurface,
|
|
54
54
|
recordPluginLifecycleHealth,
|
|
55
55
|
recordHostPolicyDenial,
|
|
56
|
+
recordQueryFeedbackObligation,
|
|
56
57
|
recordRegistryUse,
|
|
57
58
|
recordTaskEligibility,
|
|
58
59
|
recordValueEpisodeSurface,
|
|
59
60
|
queryResponseHasMatches,
|
|
60
61
|
reportDirectiveEvent,
|
|
61
62
|
reportTaskOutcomesOnStop,
|
|
62
|
-
responseRequestsRemembranceFollowup,
|
|
63
63
|
resolveApiCredential,
|
|
64
64
|
runPromptHook,
|
|
65
65
|
toolResponseIndicatesFailure,
|
|
@@ -76,6 +76,8 @@ const CONTRIBUTION_TOOLS = [
|
|
|
76
76
|
"submit_remembrance",
|
|
77
77
|
"propose_skill_idea",
|
|
78
78
|
"propose_private_skill",
|
|
79
|
+
"submit_private_lesson_candidate",
|
|
80
|
+
"retry_private_lesson_candidate",
|
|
79
81
|
"submit_suggestion",
|
|
80
82
|
"submit_resource",
|
|
81
83
|
"submit_resource_review",
|
|
@@ -371,6 +373,7 @@ export const Remembrance = async (context = {}) => {
|
|
|
371
373
|
highMatch: result?.highMatch ?? null,
|
|
372
374
|
text: guidance.trim(),
|
|
373
375
|
countsAsUse: Boolean(result?.consumed && result?.matched),
|
|
376
|
+
queryFeedback: result?.queryFeedback ?? null,
|
|
374
377
|
valueEpisode: result?.valueEpisode ?? null,
|
|
375
378
|
});
|
|
376
379
|
}
|
|
@@ -412,6 +415,11 @@ export const Remembrance = async (context = {}) => {
|
|
|
412
415
|
recordHighMatchSurface(sessionId, guidance.highMatch, env);
|
|
413
416
|
recordValueEpisodeSurface(sessionId, guidance.valueEpisode, env);
|
|
414
417
|
}
|
|
418
|
+
recordQueryFeedbackObligation(
|
|
419
|
+
sessionId,
|
|
420
|
+
guidance.queryFeedback,
|
|
421
|
+
env,
|
|
422
|
+
);
|
|
415
423
|
recordDirectiveSurface(sessionId, guidance.directive, env);
|
|
416
424
|
if (guidance.directive) {
|
|
417
425
|
await reportDirectiveEvent(
|
|
@@ -487,7 +495,6 @@ export const Remembrance = async (context = {}) => {
|
|
|
487
495
|
});
|
|
488
496
|
const decision = decideStop({ session_id: sessionId }, { env });
|
|
489
497
|
if (decision?.allow !== false || !decision?.reason) return;
|
|
490
|
-
markCurrentEngagementHandled(sessionId, env);
|
|
491
498
|
writePromptedCount(sessionId, decision.useCount ?? 1, env);
|
|
492
499
|
await notify(client, decision.reason);
|
|
493
500
|
} catch (error) {
|
|
@@ -555,6 +562,7 @@ export const Remembrance = async (context = {}) => {
|
|
|
555
562
|
const tool = toolNameFromEvent(input, output);
|
|
556
563
|
if (!tool) return;
|
|
557
564
|
const normalizedTool = tool.toLowerCase();
|
|
565
|
+
const toolArguments = toolArgumentsFromEvent(input);
|
|
558
566
|
if (toolResponseIndicatesFailure(output)) {
|
|
559
567
|
await observeHostPolicyDenial({
|
|
560
568
|
eventType: "tool.execute.after",
|
|
@@ -575,6 +583,13 @@ export const Remembrance = async (context = {}) => {
|
|
|
575
583
|
valueEpisodeFromResponse(output),
|
|
576
584
|
env,
|
|
577
585
|
);
|
|
586
|
+
observeSuccessfulCompletionTool(
|
|
587
|
+
sessionId,
|
|
588
|
+
tool,
|
|
589
|
+
toolArguments,
|
|
590
|
+
output,
|
|
591
|
+
env,
|
|
592
|
+
);
|
|
578
593
|
await recordDirectiveFollowThroughForTool(sessionId, tool, output, {
|
|
579
594
|
env,
|
|
580
595
|
});
|
|
@@ -599,6 +614,23 @@ export const Remembrance = async (context = {}) => {
|
|
|
599
614
|
selection.slug,
|
|
600
615
|
env,
|
|
601
616
|
);
|
|
617
|
+
observeSuccessfulCompletionTool(
|
|
618
|
+
sessionId,
|
|
619
|
+
tool,
|
|
620
|
+
toolArguments,
|
|
621
|
+
output,
|
|
622
|
+
env,
|
|
623
|
+
);
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
if (normalizedTool.endsWith("prepare_private_lesson_candidate")) {
|
|
627
|
+
observeSuccessfulCompletionTool(
|
|
628
|
+
sessionId,
|
|
629
|
+
tool,
|
|
630
|
+
toolArguments,
|
|
631
|
+
output,
|
|
632
|
+
env,
|
|
633
|
+
);
|
|
602
634
|
return;
|
|
603
635
|
}
|
|
604
636
|
if (
|
|
@@ -613,19 +645,26 @@ export const Remembrance = async (context = {}) => {
|
|
|
613
645
|
normalizedTool.endsWith(candidate),
|
|
614
646
|
)
|
|
615
647
|
) {
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
648
|
+
observeSuccessfulCompletionTool(
|
|
649
|
+
sessionId,
|
|
650
|
+
tool,
|
|
651
|
+
toolArguments,
|
|
652
|
+
output,
|
|
653
|
+
env,
|
|
654
|
+
);
|
|
623
655
|
return;
|
|
624
656
|
}
|
|
625
657
|
clearHighMatchSurfaceIfOpened(
|
|
626
658
|
sessionId,
|
|
627
659
|
tool,
|
|
628
|
-
|
|
660
|
+
toolArguments,
|
|
661
|
+
env,
|
|
662
|
+
);
|
|
663
|
+
observeSuccessfulCompletionTool(
|
|
664
|
+
sessionId,
|
|
665
|
+
tool,
|
|
666
|
+
toolArguments,
|
|
667
|
+
output,
|
|
629
668
|
env,
|
|
630
669
|
);
|
|
631
670
|
} catch (error) {
|