vouchington-tooling 0.25.0 → 0.26.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.
@@ -8,8 +8,7 @@ type ToolContext = {
8
8
  env: NodeJS.ProcessEnv;
9
9
  dependencies: BlackboardClientDependencies;
10
10
  };
11
- type ToolResult = string | Record<string, unknown>;
12
- export type ToolHandler = (args: Args, context: ToolContext) => Promise<ToolResult>;
11
+ export type ToolHandler = (args: Args, context: ToolContext) => Promise<Record<string, unknown>>;
13
12
  /**
14
13
  * The consumer convention for the interactive outbox. It is derived, never accepted from the
15
14
  * caller, so a credentialed, unsandboxed server cannot be pointed at an arbitrary directory.
@@ -54,14 +54,7 @@ export async function callTool(name, rawArguments, environment) {
54
54
  // The client resolves from the validated worktree, never from the server's own location.
55
55
  dependencies: { ...environment.blackboard, resolveFrom: join(worktree, 'package.json') },
56
56
  });
57
- return {
58
- content: [
59
- {
60
- type: 'text',
61
- text: typeof result === 'string' ? result : JSON.stringify(result, null, 2),
62
- },
63
- ],
64
- };
57
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
65
58
  }
66
59
  catch (error) {
67
60
  return { isError: true, content: [{ type: 'text', text: describeError(error) }] };
@@ -4,6 +4,7 @@ export declare const BLACKBOARD_ENV: {
4
4
  AGENT_BLACKBOARD_TOKEN: string;
5
5
  };
6
6
  type StoredEntry = {
7
+ sessionId?: string;
7
8
  createdAt: string;
8
9
  data: unknown;
9
10
  };
@@ -1,5 +1,6 @@
1
1
  import { type ToolHandler } from './context.mts';
2
2
  export declare const journalAppend: ToolHandler;
3
+ /** Every entry as the client returns it, oldest first. Nothing is filtered or rewritten. */
3
4
  export declare const journalEntries: ToolHandler;
4
5
  export declare const outboxStatus: ToolHandler;
5
6
  export declare const outboxFlush: ToolHandler;
@@ -1,4 +1,4 @@
1
- import { appendJournalMarkdown, feedbackOutboxStatus, flushFeedbackOutbox, formatJournalEntries, readJournal, } from '../agent-blackboard/index.mjs';
1
+ import { appendJournalMarkdown, feedbackOutboxStatus, flushFeedbackOutbox, readJournal, } from '../agent-blackboard/index.mjs';
2
2
  import { optionalRecord, optionalString, requiredChoice, requiredString, requiredStringArray, rejectUnknown, } from './args.mjs';
3
3
  import { outboxDirectory, readIdentity } from './context.mjs';
4
4
  const MODES = ['interactive', 'autonomous'];
@@ -60,7 +60,24 @@ export const journalAppend = async (args, context) => {
60
60
  });
61
61
  return { sessionId: context.sessionId, timestamp, ...result };
62
62
  };
63
- export const journalEntries = async (_args, context) => formatJournalEntries(context.sessionId, await readJournal(context.sessionId, context.env, context.dependencies));
63
+ // `Entries.get` documents no order, and `createdAt` is a service-generated ISO 8601 UTC time whose
64
+ // text order is time order. An entry without a usable `createdAt` sorts first rather than throwing.
65
+ function createdAtOf(entry) {
66
+ const createdAt = entry?.createdAt;
67
+ return typeof createdAt === 'string' ? createdAt : '';
68
+ }
69
+ function byCreatedAt(left, right) {
70
+ const leftAt = createdAtOf(left);
71
+ const rightAt = createdAtOf(right);
72
+ if (leftAt === rightAt)
73
+ return 0;
74
+ return leftAt < rightAt ? -1 : 1;
75
+ }
76
+ /** Every entry as the client returns it, oldest first. Nothing is filtered or rewritten. */
77
+ export const journalEntries = async (_args, context) => ({
78
+ sessionId: context.sessionId,
79
+ entries: (await readJournal(context.sessionId, context.env, context.dependencies)).toSorted(byCreatedAt),
80
+ });
64
81
  export const outboxStatus = async (_args, context) => ({
65
82
  sessionId: context.sessionId,
66
83
  ...feedbackOutboxStatus(outboxDirectory(context.worktree)),
@@ -97,7 +97,9 @@ export const TOOLS = [
97
97
  'repositories',
98
98
  'feedbackCoverage',
99
99
  ]),
100
- tool('journal_entries', 'Returns the journal entries of one session, oldest first, as markdown.', READ_ONLY),
100
+ tool('journal_entries', 'Returns every entry of one session, oldest first, as JSON: { sessionId, entries }. Each ' +
101
+ 'entry is exactly as the blackboard returns it ({ sessionId, createdAt, data }), including ' +
102
+ 'non-journal types such as retrospective and legacy entries without a feedback envelope.', READ_ONLY),
101
103
  tool('outbox_status', 'Reports how many unsent journal records the worktree outbox retains. sessionId identifies ' +
102
104
  'the caller; the count covers the whole outbox.', READ_ONLY),
103
105
  tool('outbox_flush', 'Delivers retained outbox records and returns the remaining count. sessionId identifies the ' +
@@ -45,7 +45,7 @@ as MCP tool errors (`isError: true`) with an actionable message rather than cras
45
45
  | Tool | Arguments besides `sessionId` and `worktree` | Returns |
46
46
  | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
47
47
  | `journal_append` | `parentSessionId`, `agent`, `version`, `mode` (`interactive` or `autonomous`), `markdown`, `sourceEventId`, `workOutcome`, `repositories`, `feedbackCoverage`, optional `timestamp`, `category` | `sessionId`, `timestamp`, delivery `status` (`delivered` with a verified receipt, or `pending`) |
48
- | `journal_entries` | none | the session's entries as markdown |
48
+ | `journal_entries` | none | `sessionId` and `entries`, every entry oldest first |
49
49
  | `outbox_status` | none | `sessionId`, `status`, `pendingCount` |
50
50
  | `outbox_flush` | none | `sessionId`, `status`, `pendingCount`, `deliveredCount` |
51
51
  | `session_ensure` | `parentSessionId`, `agent`, `version` | `sessionId`, `status` (`created` or `exists`), `archived` |
@@ -59,6 +59,13 @@ retrying the same `sourceEventId`, resend the same content and the `timestamp` t
59
59
  returned; the server fixes a default timestamp and returns it for that reason. Markdown is limited
60
60
  to 12000 bytes.
61
61
 
62
+ `journal_entries` returns `{ sessionId, entries }`. Each entry is exactly what the `agent-blackboard`
63
+ client returns (`sessionId`, `createdAt`, `data`), so `data` keeps its envelope fields such as
64
+ `repositories`, `sourceEventId`, `workOutcome`, and `feedbackCoverage`. Entries of every type come
65
+ back, including `retrospective` and legacy entries without an envelope. The client documents no
66
+ order, so they are sorted stably by `createdAt`, oldest first. An empty session returns
67
+ `entries: []`. `vouchington agent-blackboard journal entries` still prints journal markdown only.
68
+
62
69
  `sessionId` on `outbox_status`, `outbox_flush`, and `snapshot_export` only identifies the caller.
63
70
  The outbox is per worktree and the status and flush cover every record in it. Flushing an empty
64
71
  outbox does not create the directory. `snapshot_export` never accepts a destination: the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vouchington-tooling",
3
- "version": "0.25.0",
3
+ "version": "0.26.0",
4
4
  "description": "Vouchington CLI and extractable tooling libraries.",
5
5
  "homepage": "https://github.com/vouchington/vouchington-tooling/tree/main/packages/vouchington-tooling#readme",
6
6
  "bugs": {
@@ -13,38 +13,75 @@ Use when the current repository provides a journal, blackboard, or equivalent du
13
13
  record. Read local `AGENTS.md` for the provider, credential, retention, and
14
14
  subagent-identity rules.
15
15
 
16
+ Journal operations are tools of the `vouchington-tooling` MCP server (`vouchington mcp`):
17
+ `journal_append`, `journal_entries`, `outbox_status`, `outbox_flush`, `session_ensure`,
18
+ `snapshot_export`, and `session_archive`. A harness may prefix the tool names with the server name.
19
+ Every call takes an exact `sessionId`, never inferred, whose meaning depends on the tool:
20
+
21
+ - `journal_append` and `session_ensure`: the session written or ensured, which is the caller's own
22
+ session unless a runner ensures a child identity.
23
+ - `journal_entries` and `session_archive`: the session read or archived, which during distillation
24
+ belongs to another agent.
25
+ - `snapshot_export`, `outbox_status`, and `outbox_flush`: only the caller. The outbox tools cover
26
+ every record in the worktree outbox, not only that session's.
27
+
28
+ Every call may take `worktree`, the absolute path of a worktree of the current repository (the
29
+ launch worktree by default). Writing or retrying an entry needs no provider skill, temporary file,
30
+ `--file` flag, or replay command.
31
+ If these tools are not available because the server is not registered or not connected, stop and
32
+ report that the journal server is unavailable. Do not fall back to a CLI command.
33
+
16
34
  1. Capture consequential observations before filing an issue: failed or recovered checks, denied or
17
35
  approved permissions, repeated fixes, scope changes, first-party tool behavior, and architectural
18
36
  findings. Record useful resolved outcomes as well as unresolved gaps. Include bounded evidence,
19
37
  affected areas, an explicit disposition, and an existing tracking reference when present.
20
38
  Journal meaningful skips or bypasses of applicable configured workflows before completion, with
21
39
  the owning workflow or command-catalog entrypoint, reason, and observed result/action.
22
- 2. Use the shared validated envelope with storage `type: journal` or `retrospective`, canonical exact
23
- entry repositories, stable `sourceEventId`, work outcome, and explicit feedback coverage. Category
24
- is optional context; it never changes storage type or distillation eligibility. Generate routine
25
- facts and metadata through the approved composer instead of hand-authoring factual markers.
40
+ 2. Record each observation with one `journal_append` call and pass the note as its `markdown`
41
+ argument (at most 12000 bytes). Required arguments are `sessionId`, `parentSessionId` (null for a
42
+ root session), `agent`, `version`, `mode`, `markdown`, a stable `sourceEventId`, `workOutcome`,
43
+ canonical exact `repositories`, and explicit `feedbackCoverage`. Also pass an ISO 8601
44
+ `timestamp` fixed before the first attempt: the server otherwise generates one, and a failed or
45
+ timed-out call returns no result to learn it from. Nothing is written unless the
46
+ whole envelope validates. The tool writes journal entries; `category` is optional context and
47
+ never changes storage type or distillation eligibility. Generate routine facts and metadata
48
+ through the approved composer and pass its output as `markdown` instead of hand-authoring
49
+ factual markers. `journal_append` stores only journal entries: save a composed retrospective
50
+ through the retrospective skill's writer, never through `journal_append`.
26
51
  3. Preserve exact provider session and parent identities. Each agent writes only its own session.
27
- Update that session's cumulative repository union before appending; never infer another repository
28
- from prose or create a child identity from a model guess.
29
- 4. Select the repository's trusted mode explicitly. Interactive outages may retain validated,
30
- sanitized feedback in the bounded durable outbox. Report pending count and delivery state, replay
31
- with the same source identity, and continue primary work only after persistence succeeds. A full,
32
- unsafe, or unwritable outbox blocks capture; never evict or silently discard an unsent record.
33
- 5. Autonomous runners require online session ensure, a fresh admission write, and readback before
34
- launching an attempt. Terminal reporting preserves work outcome separately from feedback
35
- coverage and delivery. A filesystem outbox never grants admission or acknowledged completion.
36
- 6. Use at-least-once delivery with consumer deduplication by exact session/source identity. A
37
- transport timeout can leave a late durable write; pending or blocked is never an acknowledged
38
- receipt. Replay verifies matching content before retrying and rejects conflicting source reuse.
39
- 7. Read journal entries oldest-first for retrospectives. Record explicit none-observed with inspected
40
- scope, or not-assessed/unavailable with reason, when evidence does not establish a finding. A
41
- permission request is not proof of approval or denial; localhost refusal is not proof of sandbox
42
- enforcement. Mark partial capture and dropped counts instead of reporting clean evidence.
52
+ `journal_append` ensures that session and merges the entry's `repositories` into the session's
53
+ cumulative repository union, so list every repository the entry concerns. Never infer another
54
+ repository from prose or create a child identity from a model guess. Call `session_ensure` with
55
+ the exact identity only when a runner must confirm the session before work starts.
56
+ 4. Select the repository's trusted `mode` (`interactive` or `autonomous`) explicitly. In interactive
57
+ mode an outage may retain the validated, sanitized record in the bounded durable outbox, and
58
+ `journal_append` reports it as pending. Report the pending count from `outbox_status`, deliver
59
+ with `outbox_flush` once the provider is reachable, and continue primary work only after
60
+ persistence succeeds. A full, unsafe, or unwritable outbox blocks capture; never evict or
61
+ silently discard an unsent record.
62
+ 5. Autonomous runners require online `session_ensure`, a fresh admission `journal_append`, and
63
+ readback before launching an attempt. Give each attempt's admission entry a `sourceEventId`
64
+ unique to that attempt: reusing an earlier one returns the earlier receipt, which does not
65
+ prove a fresh write. Autonomous mode has no filesystem outbox, so a failed delivery is an error.
66
+ Terminal reporting preserves work outcome separately from feedback coverage and delivery. A
67
+ filesystem outbox never grants admission or acknowledged completion.
68
+ 6. Use at-least-once delivery with consumer deduplication by exact session/source identity. To
69
+ retry a pending or failed append, call `journal_append` again with the same `sourceEventId`,
70
+ content, and `timestamp` from the first attempt: the whole envelope must match, and conflicting
71
+ source reuse is rejected. A transport timeout can leave a late
72
+ durable write; pending or blocked is never an acknowledged receipt.
73
+ 7. Read the session's entries oldest-first with `journal_entries` for retrospectives. It returns
74
+ every entry with its envelope, including its type and repository tags, so a retrospective can
75
+ find an existing retrospective and keep entry-level tags. Record explicit
76
+ none-observed with inspected scope, or not-assessed/unavailable with reason, when evidence does
77
+ not establish a finding. A permission request is not proof of approval or denial; localhost
78
+ refusal is not proof of sandbox enforcement. Mark partial capture and dropped counts instead of
79
+ reporting clean evidence.
43
80
 
44
81
  Never search for, print, invent, or mint credentials. Durable entries and outbox records contain only
45
82
  bounded structured facts or sanitized summaries, never raw command output, transcript content,
46
83
  environment dumps, provider payloads, or secrets. Known-secret redaction supplements the author's
47
84
  minimization responsibility; it cannot prove arbitrary prose contains no undisclosed secret.
48
85
 
49
- Consumer wrappers own service configuration, trusted mode selection, commands, outbox location,
50
- issue routing, and archival authorization.
86
+ Consumer wrappers own service configuration, server registration and approval rules, trusted mode
87
+ selection, issue routing, and archival authorization. The server fixes the outbox location.
@@ -4,7 +4,7 @@
4
4
  {
5
5
  "name": "agent-workflow",
6
6
  "plugin": "vouchington-workflow",
7
- "pluginVersion": "0.9.0",
7
+ "pluginVersion": "0.10.0",
8
8
  "path": "agent-workflow/SKILL.md",
9
9
  "prerequisites": ["github-issue", "pr-description", "review-ci-logs"]
10
10
  },
@@ -18,13 +18,13 @@
18
18
  {
19
19
  "name": "blackboard",
20
20
  "plugin": "vouchington-workflow",
21
- "pluginVersion": "0.9.0",
21
+ "pluginVersion": "0.10.0",
22
22
  "path": "blackboard/SKILL.md"
23
23
  },
24
24
  {
25
25
  "name": "dependabot",
26
26
  "plugin": "vouchington-workflow",
27
- "pluginVersion": "0.9.0",
27
+ "pluginVersion": "0.10.0",
28
28
  "path": "dependabot/SKILL.md",
29
29
  "prerequisites": ["github-actions-checklist"]
30
30
  },
@@ -38,26 +38,26 @@
38
38
  {
39
39
  "name": "git-commit-checklist",
40
40
  "plugin": "vouchington-workflow",
41
- "pluginVersion": "0.9.0",
41
+ "pluginVersion": "0.10.0",
42
42
  "path": "git-commit-checklist/SKILL.md"
43
43
  },
44
44
  {
45
45
  "name": "github-actions-authoring",
46
46
  "plugin": "vouchington-workflow",
47
- "pluginVersion": "0.9.0",
47
+ "pluginVersion": "0.10.0",
48
48
  "path": "github-actions-authoring/SKILL.md",
49
49
  "prerequisites": ["github-actions-checklist"]
50
50
  },
51
51
  {
52
52
  "name": "github-actions-checklist",
53
53
  "plugin": "vouchington-workflow",
54
- "pluginVersion": "0.9.0",
54
+ "pluginVersion": "0.10.0",
55
55
  "path": "github-actions-checklist/SKILL.md"
56
56
  },
57
57
  {
58
58
  "name": "github-issue",
59
59
  "plugin": "vouchington-workflow",
60
- "pluginVersion": "0.9.0",
60
+ "pluginVersion": "0.10.0",
61
61
  "path": "github-issue/SKILL.md"
62
62
  },
63
63
  {
@@ -70,26 +70,26 @@
70
70
  {
71
71
  "name": "npm-publishing",
72
72
  "plugin": "vouchington-workflow",
73
- "pluginVersion": "0.9.0",
73
+ "pluginVersion": "0.10.0",
74
74
  "path": "npm-publishing/SKILL.md"
75
75
  },
76
76
  {
77
77
  "name": "organize-github-issues",
78
78
  "plugin": "vouchington-workflow",
79
- "pluginVersion": "0.9.0",
79
+ "pluginVersion": "0.10.0",
80
80
  "path": "organize-github-issues/SKILL.md",
81
81
  "prerequisites": ["github-issue"]
82
82
  },
83
83
  {
84
84
  "name": "package-json-checklist",
85
85
  "plugin": "vouchington-workflow",
86
- "pluginVersion": "0.9.0",
86
+ "pluginVersion": "0.10.0",
87
87
  "path": "package-json-checklist/SKILL.md"
88
88
  },
89
89
  {
90
90
  "name": "planning",
91
91
  "plugin": "vouchington-workflow",
92
- "pluginVersion": "0.9.0",
92
+ "pluginVersion": "0.10.0",
93
93
  "path": "planning/SKILL.md",
94
94
  "prerequisites": ["github-issue"]
95
95
  },
@@ -115,53 +115,53 @@
115
115
  {
116
116
  "name": "pr-description",
117
117
  "plugin": "vouchington-workflow",
118
- "pluginVersion": "0.9.0",
118
+ "pluginVersion": "0.10.0",
119
119
  "path": "pr-description/SKILL.md"
120
120
  },
121
121
  {
122
122
  "name": "retrospective",
123
123
  "plugin": "vouchington-workflow",
124
- "pluginVersion": "0.9.0",
124
+ "pluginVersion": "0.10.0",
125
125
  "path": "retrospective/SKILL.md"
126
126
  },
127
127
  {
128
128
  "name": "retrospective-distill",
129
129
  "plugin": "vouchington-workflow",
130
- "pluginVersion": "0.9.0",
130
+ "pluginVersion": "0.10.0",
131
131
  "path": "retrospective-distill/SKILL.md",
132
132
  "prerequisites": ["github-issue"]
133
133
  },
134
134
  {
135
135
  "name": "review-ci-logs",
136
136
  "plugin": "vouchington-workflow",
137
- "pluginVersion": "0.9.0",
137
+ "pluginVersion": "0.10.0",
138
138
  "path": "review-ci-logs/SKILL.md",
139
139
  "prerequisites": ["github-actions-checklist", "pr-description"]
140
140
  },
141
141
  {
142
142
  "name": "review-github-issue-taxonomy",
143
143
  "plugin": "vouchington-workflow",
144
- "pluginVersion": "0.9.0",
144
+ "pluginVersion": "0.10.0",
145
145
  "path": "review-github-issue-taxonomy/SKILL.md",
146
146
  "prerequisites": ["github-issue"]
147
147
  },
148
148
  {
149
149
  "name": "revisit-followups",
150
150
  "plugin": "vouchington-workflow",
151
- "pluginVersion": "0.9.0",
151
+ "pluginVersion": "0.10.0",
152
152
  "path": "revisit-followups/SKILL.md",
153
153
  "prerequisites": ["github-issue"]
154
154
  },
155
155
  {
156
156
  "name": "stacked-prs",
157
157
  "plugin": "vouchington-workflow",
158
- "pluginVersion": "0.9.0",
158
+ "pluginVersion": "0.10.0",
159
159
  "path": "stacked-prs/SKILL.md"
160
160
  },
161
161
  {
162
162
  "name": "static-analysis-checklist",
163
163
  "plugin": "vouchington-workflow",
164
- "pluginVersion": "0.9.0",
164
+ "pluginVersion": "0.10.0",
165
165
  "path": "static-analysis-checklist/SKILL.md",
166
166
  "prerequisites": ["github-actions-checklist"]
167
167
  },
@@ -12,26 +12,48 @@ Local policy overrides these defaults; do not reload an already-read adapter or
12
12
  Use when completed retrospectives or journals should become durable follow-up work. Read local
13
13
  `AGENTS.md`, issue policy, and journal retention rules before any mutation.
14
14
 
15
- 1. Enumerate only completed, eligible session records. For repository-scoped work, filter sessions
16
- by repository membership and use only entries attributed to that repository. Leave untagged
17
- legacy records unclassified. Do not infer their repository. Leave in-progress sessions intact.
18
- 2. Validate storage type and the shared envelope independently of optional category. Never repair
15
+ 1. Enumerate only completed, eligible session records with the `snapshot_export` tool of the
16
+ `vouchington-tooling` MCP server, narrowing by `agent`, `version`, `parentSessionId`, exact
17
+ `data` fields, `dataArrayContains`, and `inactiveForHours`. It exports non-archived sessions to a
18
+ private local file and returns the path, counts, checksum, and manifest, never the records.
19
+ Before exporting, call `outbox_flush` and then `outbox_status` for every worktree that
20
+ `git worktree list` reports, passing each path as `worktree`, and stop if any still reports
21
+ pending records: an archived session refuses later delivery, so a retained record would never
22
+ be distilled. Outboxes in removed worktrees or on other machines cannot be drained this way, so
23
+ select with `inactiveForHours` to give them time to deliver. Leave in-progress sessions intact.
24
+ If the server is not connected, stop and report it; do not fall back to a CLI command.
25
+ 2. Before using any record, verify the file against the returned checksum, counts, and terminal
26
+ manifest with the consumer's approved snapshot reader, and stop on a mismatch rather than
27
+ treating missing records as absent. Read full records, with their storage type, repository
28
+ tags, source identity, coverage, and outcomes, from that file. Do not distill from
29
+ `journal_entries`: it reads one session at a time and has no checksum or manifest to show that
30
+ the read is complete. For repository-scoped work, filter sessions by
31
+ repository membership (`dataArrayContains` with `repositories` and the exact `owner/name`) and
32
+ use only entries attributed to that repository. Leave untagged legacy records unclassified. Do
33
+ not infer their repository.
34
+ 3. Validate storage type and the shared envelope independently of optional category. Never repair
19
35
  unknown legacy types or repository provenance by inference. Quarantine malformed sessions with
20
36
  an explicit reason while processing valid unrelated sessions. Deduplicate at-least-once records
21
37
  by exact session/source identity and reject conflicting duplicate content. Retain coverage,
22
38
  dropped counts, requested versus observed outcomes, and useful resolved findings.
23
- 3. Cluster findings by root cause. Prefer a few broad actionable themes over many narrow issues.
39
+ 4. Cluster findings by root cause. Prefer a few broad actionable themes over many narrow issues.
24
40
  Treat a finding already linked to an open tracker as context, not a duplicate.
25
- 4. Verify each candidate against the current base. Search existing issues and open changes before
41
+ 5. Verify each candidate against the current base. Search existing issues and open changes before
26
42
  drafting. Skip work that is complete, explicitly rejected, or already covered. A first-party version
27
43
  bump is not proof of resolution: verify the adopted change against the original finding before
28
44
  deferring. Capture a new observation in the journal before filing it.
29
- 5. Draft self-contained issues with the problem, concrete proposed work, relevant areas, and
45
+ 6. Draft self-contained issues with the problem, concrete proposed work, relevant areas, and
30
46
  validation. Route every authorized creation through
31
47
  [github-issue](../github-issue/SKILL.md), including its repository gate, label approval, and
32
48
  denied-external tracking behavior.
33
- 6. Archive only records fully processed across every represented repository, under the repository's
34
- retention rules. A one-repository pass leaves a multi-repository session active until the other
49
+ 7. Archive only verified records fully processed across every represented repository, and never
50
+ while any worktree's `outbox_status` reports pending records, under the repository's retention
51
+ rules. Make one `session_archive` call per session, whose `sessionId` is the archived session,
52
+ not the caller. Immediately before each call, read that session with `journal_entries` and
53
+ archive only if its entries match the verified snapshot's by source identity; otherwise leave it
54
+ for the next pass, because an entry added after the export would never be distilled.
55
+ Archiving makes the session's metadata immutable, so it needs the archival authorization that
56
+ local policy requires. A one-repository pass leaves a multi-repository session active until the other
35
57
  repositories are reviewed. Report reviewed, fixed, duplicate, deferred, quarantined, and
36
58
  actionable dispositions with reasons. Keep the top five themes in human prose without dropping
37
59
  underlying findings or unresolved records.
@@ -40,8 +62,10 @@ Use source records only for local verification and leave them in the repository'
40
62
  or retention system. Public issue bodies contain only the minimum bounded facts or redacted
41
63
  summaries needed to establish the problem, proposed work, relevant areas, and validation. Never
42
64
  embed unredacted logs, command output, environment details, provider payloads, or transcript
43
- content.
65
+ content. A snapshot file is a private local copy of source records: never commit or attach it, or
66
+ copy its contents into an issue.
44
67
 
45
- This skill supplies no journal API, issue repository, labels, milestones, projects, archival
46
- command, or approval model. Consumer wrappers cannot weaken this export boundary; they provide only
47
- those local details.
68
+ This skill supplies no issue repository, labels, milestones, projects, or approval model; it reads
69
+ sessions only from the snapshot file that `snapshot_export` writes, and archives them only with
70
+ `session_archive`. Consumer wrappers cannot weaken this export
71
+ boundary; they provide only those local details.