Skip to content

Commit e6b4fc5

Browse files
committed
release: prepare paperclip-aperture 0.2.2
1 parent 957409b commit e6b4fc5

10 files changed

Lines changed: 591 additions & 73 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ node_modules
33
.paperclip-sdk
44
*.tgz
55
.DS_Store
6+
tmp/

README.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ and agents attention now? actually sees to th
6868
- issue-aware operator language such as `review required`, `blocked`, and targeted recommended moves
6969
- agent-aware routing that distinguishes known company agents from human/operator roles when issue text references them
7070
- a plugin-local deterministic semantic mapping layer that interprets Paperclip issue, approval, and agent signals before publishing them into Aperture Core
71+
- richer semantic continuity hints on mapped issue events, including `supersedes` and `resolves` relationships where Paperclip-specific intent is clear
72+
- document-aware review interpretation for memo/spec-backed issues so Focus can tell the difference between `review is blocked on the artifact` and `the artifact is attached, monitor instead`
7173
- dynamic re-stacking so items can move between `now`, `next`, and `ambient` as new evidence arrives
7274
- inline issue commenting from the Focus surface when a Paperclip issue supports written response
7375
- durable acknowledge/suppression behavior backed by plugin state and ledger replay
@@ -104,14 +106,19 @@ Before releasing, run:
104106
pnpm release:check
105107
```
106108

107-
For a live local Paperclip smoke test:
109+
For a live local Paperclip smoke test, start Paperclip first:
108110

109111
```bash
110112
pnpm build
113+
npx paperclipai run -i default
114+
```
115+
116+
Then, in a second terminal:
117+
118+
```bash
111119
npx paperclipai context set --api-base http://localhost:3100
112120
npx paperclipai plugin uninstall tomismeta.paperclip-aperture --force
113121
npx paperclipai plugin install --local .
114-
npx paperclipai run -i default
115122
```
116123

117124
Then open `http://127.0.0.1:3100/APE/aperture` and verify:
@@ -121,6 +128,7 @@ Then open `http://127.0.0.1:3100/APE/aperture` and verify:
121128
- issue comments post successfully from Focus
122129
- approval actions update Focus correctly
123130
- resolved blocker comments downgrade stale `Now` items
131+
- attached issue documents downgrade stale `share the memo/spec` review blockers into monitor-only follow-up
124132

125133
## Links
126134

docs/RELEASE-0.2.2.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# paperclip-aperture 0.2.2
2+
3+
`0.2.2` keeps the `0.2.x` product surface intact while tightening the semantic bridge into Aperture Core and making review flows more document-aware.
4+
5+
## Highlights
6+
7+
- Added richer semantic continuity hints on mapped issue events
8+
- Added better semantic confidence shaping for plugin-authored issue semantics
9+
- Added document-aware review interpretation for memo/spec-backed issues
10+
- Added `issue.documents.read` support to the plugin worker
11+
12+
## What Changed
13+
14+
- issue events now project clearer core-shaped relation hints such as:
15+
- `same_issue`
16+
- `supersedes`
17+
- `resolves`
18+
- the plugin no longer over-stamps confidence on approval and failure paths when core can infer it from the canonical event shape
19+
- reconciliation now checks issue documents for blocked and `in_review` issues
20+
- if a review-blocking memo/spec request has been satisfied by a later document attachment, Focus downgrades that item from interruptive review work into monitor-only follow-up
21+
22+
## Why This Matters
23+
24+
- better semantic relation hints improve continuity and episode-tracking behavior in Aperture Core without forcing the plugin to abandon its Paperclip-specific ontology
25+
- document-aware review handling makes Focus less stale in real Paperclip workflows where the critical artifact lives on the issue, not just in comments
26+
- the architectural line remains the same:
27+
- Aperture Core owns bounded semantic substrate and attention judgment
28+
- paperclip-aperture owns Paperclip-specific interpretation and operator language
29+
30+
## Dependency Snapshot
31+
32+
- `@tomismeta/aperture-core@^0.4.0`
33+
- `@paperclipai/plugin-sdk@2026.318.0`
34+
35+
## Validation
36+
37+
- `pnpm test`
38+
- `pnpm typecheck`
39+
- `pnpm build`
40+
- live smoke-tested against a running local Paperclip instance, including document attach -> ambient downgrade behavior

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@tomismeta/paperclip-aperture",
3-
"version": "0.2.1",
3+
"version": "0.2.2",
44
"type": "module",
55
"private": false,
66
"description": "The live attention layer for Paperclip, powered by Aperture's deterministic attention engine.",

src/aperture/event-mapper.ts

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ import {
1818
linkedIssuesItem,
1919
requestedAmountItem,
2020
} from "./attention-context.js";
21+
import {
22+
analyzeIssueTextSemantics,
23+
issueRelationTarget,
24+
} from "./issue-intelligence.js";
2125

2226
type ExtendedPluginEventType =
2327
| PluginEvent["eventType"]
@@ -160,10 +164,6 @@ function issueDisplayTitle(event: MappablePluginEvent, fallback: string): string
160164
return fallback;
161165
}
162166

163-
function issueRelationTarget(issueId: string): string {
164-
return `issue:${issueId}`;
165-
}
166-
167167
function relationHintsForIssueTargets(issueIds: string[] | undefined): SourceEvent["semanticHints"] | undefined {
168168
if (!issueIds || issueIds.length === 0) return undefined;
169169

@@ -175,18 +175,38 @@ function relationHintsForIssueTargets(issueIds: string[] | undefined): SourceEve
175175
};
176176
}
177177

178+
function issueSemanticText(payload: unknown): string {
179+
return [
180+
readPayloadString(payload, "bodySnippet"),
181+
readPayloadString(payload, "summary"),
182+
readPayloadString(payload, "description"),
183+
readPayloadString(payload, "title"),
184+
readPayloadString(payload, "issueTitle"),
185+
]
186+
.filter((value): value is string => !!value)
187+
.join("\n");
188+
}
189+
178190
function issueSemanticHints(event: MappablePluginEvent): SourceEvent["semanticHints"] | undefined {
179-
return event.entityType === "issue" && event.entityId
180-
? relationHintsForIssueTargets([event.entityId])
181-
: undefined;
191+
if (event.entityType !== "issue" || !event.entityId) return undefined;
192+
193+
const semanticAnalysis = analyzeIssueTextSemantics({
194+
text: issueSemanticText(event.payload),
195+
identifier: readPayloadString(event.payload, "identifier"),
196+
issueTarget: issueRelationTarget(event.entityId),
197+
});
198+
199+
return {
200+
...(semanticAnalysis.semanticConfidence ? { confidence: semanticAnalysis.semanticConfidence } : {}),
201+
...(semanticAnalysis.relationHints.length > 0 ? { relationHints: semanticAnalysis.relationHints } : {}),
202+
};
182203
}
183204

184205
function approvalSemanticHints(
185206
budgetOverride: boolean,
186207
linkedIssueIds: string[] | undefined,
187208
): SourceEvent["semanticHints"] {
188209
return {
189-
confidence: "high",
190210
whyNow: approvalBlockingWhyNow(budgetOverride),
191211
factors: budgetOverride
192212
? ["budget stop", "approval", "operator decision"]
@@ -197,7 +217,6 @@ function approvalSemanticHints(
197217

198218
function pendingApprovalSemanticHints(): SourceEvent["semanticHints"] {
199219
return {
200-
confidence: "high",
201220
whyNow: pendingApprovalEventWhyNow(),
202221
factors: ["pending approval"],
203222
};
@@ -206,7 +225,6 @@ function pendingApprovalSemanticHints(): SourceEvent["semanticHints"] {
206225
function runFailureSemanticHints(): SourceEvent["semanticHints"] {
207226
return {
208227
intentFrame: "failure",
209-
confidence: "high",
210228
whyNow: runFailedWhyNow(),
211229
factors: ["run failed", "operator review"],
212230
};

0 commit comments

Comments
 (0)