@lmzhen/dsh-skill-usage 0.3.61 → 0.3.63

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/lib/index.js CHANGED
@@ -59,7 +59,7 @@ var SkillUsageRegistry = class extends Service {
59
59
  constructor(ctx, config = {}) {
60
60
  super(ctx, "skillUsage");
61
61
  this.root = resolveSkillsRoot(config);
62
- this.eventsHome = config.eventsHome || evolutionRoot();
62
+ this.eventsHome = config.eventsHome?.trim() || evolutionRoot();
63
63
  this.io = evolutionIoAdapter(() => ctx.evolutionIo.provider());
64
64
  ctx.effect(() => {
65
65
  return ctx.on("session/event", (_session, event) => {
@@ -148,7 +148,11 @@ var SkillUsageRegistry = class extends Service {
148
148
  else bumpPatch(map, normalized, at);
149
149
  });
150
150
  }
151
- /** Read-only snapshot of the sidecar (no disk write — reading never mutates). */
151
+ /** Read-only snapshot of the sidecar (no disk write — reading never mutates).
152
+ * P3-18 (v14): unlike `mutate()` this takes no cross-process transact lock.
153
+ * That is safe by construction: every writer commits through tmp+rename, so a
154
+ * reader observes a complete generation (old or new), never a torn file, and
155
+ * the lock exists for the read-modify-write cycle this method does not do. */
152
156
  async report() {
153
157
  const run = this.chain.then(async () => new Map(await loadUsage(this.root, this.io)));
154
158
  this.chain = run.then(() => void 0, () => void 0);
@@ -197,14 +201,22 @@ var SkillUsageRegistry = class extends Service {
197
201
  async invalidate() {
198
202
  await this.chain;
199
203
  }
200
- /** Write feedback-derived quality onto the usage sidecar; curator reads it. */
201
- async setQuality(name, score, warn) {
204
+ /** P1-1 (v15): write the FEEDBACK-owned quality signal onto the usage
205
+ * sidecar. Renamed from `setQuality` (it no longer writes the fields the
206
+ * name claims): the curator's six-factor `scoreTree` overwrites
207
+ * `quality_score`/`quality_warn` on every run BEFORE the lifecycle engine
208
+ * reads them, so feedback written to those fields was a dead channel — the
209
+ * value never survived to a decision. The lifecycle engine and the scope
210
+ * view now read the union `quality_warn || feedback_warn`, so a negative
211
+ * feedback is decision-relevant again. Field-ownership contract: see
212
+ * `UsageRecord` in evolution-core/usage.ts. */
213
+ async setFeedbackQuality(name, score, warn) {
202
214
  const normalized = name.trim();
203
215
  await this.mutate((map) => {
204
216
  const record = map.get(normalized);
205
217
  if (!record) return;
206
- record.quality_score = score;
207
- record.quality_warn = warn;
218
+ record.feedback_score = score;
219
+ record.feedback_warn = warn;
208
220
  });
209
221
  }
210
222
  };
@@ -60,7 +60,11 @@ export declare class SkillUsageRegistry extends Service {
60
60
  */
61
61
  private mutate;
62
62
  record(name: string, kind: 'use' | 'view' | 'patch', at?: Date): Promise<void>;
63
- /** Read-only snapshot of the sidecar (no disk write — reading never mutates). */
63
+ /** Read-only snapshot of the sidecar (no disk write — reading never mutates).
64
+ * P3-18 (v14): unlike `mutate()` this takes no cross-process transact lock.
65
+ * That is safe by construction: every writer commits through tmp+rename, so a
66
+ * reader observes a complete generation (old or new), never a torn file, and
67
+ * the lock exists for the read-modify-write cycle this method does not do. */
64
68
  report(): Promise<UsageMap>;
65
69
  markAgentCreated(name: string): Promise<void>;
66
70
  /**
@@ -86,8 +90,16 @@ export declare class SkillUsageRegistry extends Service {
86
90
  * (tests use it as a drain barrier); kept by declaration.
87
91
  */
88
92
  invalidate(): Promise<void>;
89
- /** Write feedback-derived quality onto the usage sidecar; curator reads it. */
90
- setQuality(name: string, score: number, warn: boolean): Promise<void>;
93
+ /** P1-1 (v15): write the FEEDBACK-owned quality signal onto the usage
94
+ * sidecar. Renamed from `setQuality` (it no longer writes the fields the
95
+ * name claims): the curator's six-factor `scoreTree` overwrites
96
+ * `quality_score`/`quality_warn` on every run BEFORE the lifecycle engine
97
+ * reads them, so feedback written to those fields was a dead channel — the
98
+ * value never survived to a decision. The lifecycle engine and the scope
99
+ * view now read the union `quality_warn || feedback_warn`, so a negative
100
+ * feedback is decision-relevant again. Field-ownership contract: see
101
+ * `UsageRecord` in evolution-core/usage.ts. */
102
+ setFeedbackQuality(name: string, score: number, warn: boolean): Promise<void>;
91
103
  }
92
104
  export default SkillUsageRegistry;
93
105
  //# sourceMappingURL=index.d.ts.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lmzhen/dsh-skill-usage",
3
3
  "description": "Skill usage telemetry service (community build)",
4
- "version": "0.3.61",
4
+ "version": "0.3.63",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -31,18 +31,18 @@
31
31
  "license": "MIT",
32
32
  "dependencies": {
33
33
  "@deepseek-ai/schemastery": "^3.18.1",
34
- "@lmzhen/dsh-evolution-core": "^0.3.61"
34
+ "@lmzhen/dsh-evolution-core": "^0.3.63"
35
35
  },
36
36
  "peerDependencies": {
37
37
  "@deepseek-ai/cordis": "^4.0.1",
38
38
  "@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
39
39
  "@deepseek-ai/dsh-session": "^0.1.1-rc.2",
40
- "@lmzhen/dsh-evolution-io": "^0.3.61"
40
+ "@lmzhen/dsh-evolution-io": "^0.3.63"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
44
44
  "@deepseek-ai/dsh-session": "^0.1.1-rc.2",
45
- "@lmzhen/dsh-evolution-core": "^0.3.61",
46
- "@lmzhen/dsh-evolution-io": "^0.3.61"
45
+ "@lmzhen/dsh-evolution-core": "^0.3.63",
46
+ "@lmzhen/dsh-evolution-io": "^0.3.63"
47
47
  }
48
48
  }