@jinn-network/core 0.1.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.
Files changed (111) hide show
  1. package/dist/canonical-json.d.ts +1 -0
  2. package/dist/canonical-json.js +67 -0
  3. package/dist/captured-task.d.ts +140 -0
  4. package/dist/captured-task.js +122 -0
  5. package/dist/contribution-store.d.ts +97 -0
  6. package/dist/contribution-store.js +770 -0
  7. package/dist/corpus-read/acquire.d.ts +39 -0
  8. package/dist/corpus-read/acquire.js +212 -0
  9. package/dist/corpus-read/cache.d.ts +14 -0
  10. package/dist/corpus-read/cache.js +17 -0
  11. package/dist/corpus-read/capture-meta.d.ts +16 -0
  12. package/dist/corpus-read/capture-meta.js +18 -0
  13. package/dist/corpus-read/create-corpus.d.ts +2 -0
  14. package/dist/corpus-read/create-corpus.js +97 -0
  15. package/dist/corpus-read/fetch-artifact.d.ts +21 -0
  16. package/dist/corpus-read/fetch-artifact.js +32 -0
  17. package/dist/corpus-read/fetch.d.ts +12 -0
  18. package/dist/corpus-read/fetch.js +24 -0
  19. package/dist/corpus-read/http-discovery.d.ts +9 -0
  20. package/dist/corpus-read/http-discovery.js +128 -0
  21. package/dist/corpus-read/index.d.ts +10 -0
  22. package/dist/corpus-read/index.js +10 -0
  23. package/dist/corpus-read/ipfs.d.ts +5 -0
  24. package/dist/corpus-read/ipfs.js +72 -0
  25. package/dist/corpus-read/route-resolver.d.ts +16 -0
  26. package/dist/corpus-read/route-resolver.js +19 -0
  27. package/dist/corpus-read/types.d.ts +177 -0
  28. package/dist/corpus-read/types.js +42 -0
  29. package/dist/envelope.d.ts +134 -0
  30. package/dist/envelope.js +162 -0
  31. package/dist/evidence-adapter.d.ts +26 -0
  32. package/dist/evidence-adapter.js +321 -0
  33. package/dist/evidence-filesystem.d.ts +40 -0
  34. package/dist/evidence-filesystem.js +267 -0
  35. package/dist/evidence-index.d.ts +117 -0
  36. package/dist/evidence-index.js +1083 -0
  37. package/dist/evidence-store-lock.d.ts +2 -0
  38. package/dist/evidence-store-lock.js +208 -0
  39. package/dist/execution-envelope.d.ts +3142 -0
  40. package/dist/execution-envelope.js +203 -0
  41. package/dist/index.d.ts +12 -0
  42. package/dist/index.js +12 -0
  43. package/dist/manifest.d.ts +75 -0
  44. package/dist/manifest.js +184 -0
  45. package/dist/paired.d.ts +68 -0
  46. package/dist/paired.js +92 -0
  47. package/dist/scrub/build.d.ts +52 -0
  48. package/dist/scrub/build.js +84 -0
  49. package/dist/scrub/emit-scrub.d.ts +41 -0
  50. package/dist/scrub/emit-scrub.js +87 -0
  51. package/dist/scrub/index.d.ts +12 -0
  52. package/dist/scrub/index.js +12 -0
  53. package/dist/scrub/key-policy.d.ts +20 -0
  54. package/dist/scrub/key-policy.js +42 -0
  55. package/dist/scrub/layer2.d.ts +23 -0
  56. package/dist/scrub/layer2.js +32 -0
  57. package/dist/scrub/ml-pii-stage.d.ts +24 -0
  58. package/dist/scrub/ml-pii-stage.js +42 -0
  59. package/dist/scrub/openredaction-stage.d.ts +196 -0
  60. package/dist/scrub/openredaction-stage.js +270 -0
  61. package/dist/scrub/pii-build.d.ts +38 -0
  62. package/dist/scrub/pii-build.js +67 -0
  63. package/dist/scrub/pipeline.d.ts +38 -0
  64. package/dist/scrub/pipeline.js +83 -0
  65. package/dist/scrub/plain-patterns-stage.d.ts +31 -0
  66. package/dist/scrub/plain-patterns-stage.js +84 -0
  67. package/dist/scrub/secretlint-stage.d.ts +36 -0
  68. package/dist/scrub/secretlint-stage.js +249 -0
  69. package/dist/scrub/transformers-detector.d.ts +35 -0
  70. package/dist/scrub/transformers-detector.js +67 -0
  71. package/dist/scrub/types.d.ts +25 -0
  72. package/dist/scrub/types.js +1 -0
  73. package/dist/session-provenance.d.ts +75 -0
  74. package/dist/session-provenance.js +20 -0
  75. package/dist/skill-artifact.d.ts +442 -0
  76. package/dist/skill-artifact.js +136 -0
  77. package/dist/trajectory/hash-chain.d.ts +18 -0
  78. package/dist/trajectory/hash-chain.js +47 -0
  79. package/dist/trajectory/index.d.ts +4 -0
  80. package/dist/trajectory/index.js +4 -0
  81. package/dist/trajectory/schema.d.ts +606 -0
  82. package/dist/trajectory/schema.js +110 -0
  83. package/dist/trajectory/transcript-parsers/aider-history.d.ts +42 -0
  84. package/dist/trajectory/transcript-parsers/aider-history.js +181 -0
  85. package/dist/trajectory/transcript-parsers/claude-code-jsonl.d.ts +37 -0
  86. package/dist/trajectory/transcript-parsers/claude-code-jsonl.js +142 -0
  87. package/dist/trajectory/transcript-parsers/codex-session.d.ts +42 -0
  88. package/dist/trajectory/transcript-parsers/codex-session.js +235 -0
  89. package/dist/trajectory/transcript-parsers/continue-devdata.d.ts +41 -0
  90. package/dist/trajectory/transcript-parsers/continue-devdata.js +190 -0
  91. package/dist/trajectory/transcript-parsers/cursor-sqlite.d.ts +38 -0
  92. package/dist/trajectory/transcript-parsers/cursor-sqlite.js +118 -0
  93. package/dist/trajectory/transcript-parsers/gemini-session.d.ts +35 -0
  94. package/dist/trajectory/transcript-parsers/gemini-session.js +137 -0
  95. package/dist/trajectory/transcript-parsers/index.d.ts +7 -0
  96. package/dist/trajectory/transcript-parsers/index.js +7 -0
  97. package/dist/trajectory/transcript-parsers/types.d.ts +101 -0
  98. package/dist/trajectory/transcript-parsers/types.js +32 -0
  99. package/dist/trajectory/transcript-to-spans/attrs.d.ts +4 -0
  100. package/dist/trajectory/transcript-to-spans/attrs.js +30 -0
  101. package/dist/trajectory/transcript-to-spans/claude-code-stream-json.d.ts +8 -0
  102. package/dist/trajectory/transcript-to-spans/claude-code-stream-json.js +162 -0
  103. package/dist/trajectory/transcript-to-spans/codex-exec-json.d.ts +8 -0
  104. package/dist/trajectory/transcript-to-spans/codex-exec-json.js +253 -0
  105. package/dist/trajectory/transcript-to-spans/index.d.ts +4 -0
  106. package/dist/trajectory/transcript-to-spans/index.js +4 -0
  107. package/dist/trajectory/transcript-to-spans/types.d.ts +18 -0
  108. package/dist/trajectory/transcript-to-spans/types.js +1 -0
  109. package/dist/window.d.ts +12 -0
  110. package/dist/window.js +5 -0
  111. package/package.json +67 -0
@@ -0,0 +1,75 @@
1
+ import { z } from 'zod/v3';
2
+ export declare const SessionProvenanceSchema: z.ZodObject<{
3
+ sessionId: z.ZodString;
4
+ capturedAt: z.ZodString;
5
+ originatingTool: z.ZodObject<{
6
+ name: z.ZodString;
7
+ version: z.ZodOptional<z.ZodString>;
8
+ }, "strip", z.ZodTypeAny, {
9
+ name: string;
10
+ version?: string | undefined;
11
+ }, {
12
+ name: string;
13
+ version?: string | undefined;
14
+ }>;
15
+ repo: z.ZodOptional<z.ZodObject<{
16
+ remoteUrl: z.ZodOptional<z.ZodString>;
17
+ commitHash: z.ZodOptional<z.ZodString>;
18
+ branch: z.ZodOptional<z.ZodString>;
19
+ }, "strip", z.ZodTypeAny, {
20
+ remoteUrl?: string | undefined;
21
+ commitHash?: string | undefined;
22
+ branch?: string | undefined;
23
+ }, {
24
+ remoteUrl?: string | undefined;
25
+ commitHash?: string | undefined;
26
+ branch?: string | undefined;
27
+ }>>;
28
+ license: z.ZodObject<{
29
+ spdxId: z.ZodOptional<z.ZodString>;
30
+ operatorAssertion: z.ZodEnum<["asserted", "unspecified"]>;
31
+ }, "strip", z.ZodTypeAny, {
32
+ operatorAssertion: "asserted" | "unspecified";
33
+ spdxId?: string | undefined;
34
+ }, {
35
+ operatorAssertion: "asserted" | "unspecified";
36
+ spdxId?: string | undefined;
37
+ }>;
38
+ /** The single `share` consent (mono#1714): may a mined task be published. */
39
+ publishMinedTasksConsent: z.ZodOptional<z.ZodBoolean>;
40
+ }, "strip", z.ZodTypeAny, {
41
+ sessionId: string;
42
+ capturedAt: string;
43
+ originatingTool: {
44
+ name: string;
45
+ version?: string | undefined;
46
+ };
47
+ license: {
48
+ operatorAssertion: "asserted" | "unspecified";
49
+ spdxId?: string | undefined;
50
+ };
51
+ publishMinedTasksConsent?: boolean | undefined;
52
+ repo?: {
53
+ remoteUrl?: string | undefined;
54
+ commitHash?: string | undefined;
55
+ branch?: string | undefined;
56
+ } | undefined;
57
+ }, {
58
+ sessionId: string;
59
+ capturedAt: string;
60
+ originatingTool: {
61
+ name: string;
62
+ version?: string | undefined;
63
+ };
64
+ license: {
65
+ operatorAssertion: "asserted" | "unspecified";
66
+ spdxId?: string | undefined;
67
+ };
68
+ publishMinedTasksConsent?: boolean | undefined;
69
+ repo?: {
70
+ remoteUrl?: string | undefined;
71
+ commitHash?: string | undefined;
72
+ branch?: string | undefined;
73
+ } | undefined;
74
+ }>;
75
+ export type SessionProvenance = z.infer<typeof SessionProvenanceSchema>;
@@ -0,0 +1,20 @@
1
+ import { z } from 'zod/v3';
2
+ export const SessionProvenanceSchema = z.object({
3
+ sessionId: z.string().min(1),
4
+ capturedAt: z.string().datetime(),
5
+ originatingTool: z.object({
6
+ name: z.string(),
7
+ version: z.string().optional(),
8
+ }),
9
+ repo: z.object({
10
+ remoteUrl: z.string().optional(),
11
+ commitHash: z.string().regex(/^[0-9a-f]{40}$/).optional(),
12
+ branch: z.string().optional(),
13
+ }).optional(),
14
+ license: z.object({
15
+ spdxId: z.string().optional(),
16
+ operatorAssertion: z.enum(['asserted', 'unspecified']),
17
+ }),
18
+ /** The single `share` consent (mono#1714): may a mined task be published. */
19
+ publishMinedTasksConsent: z.boolean().optional(),
20
+ });
@@ -0,0 +1,442 @@
1
+ import { z } from 'zod/v3';
2
+ /**
3
+ * jinn.skill.v1 — first-class skill artifact (issue #1394).
4
+ *
5
+ * A skill (SKILL.md + optional companion files + machine-readable
6
+ * provenance) carried as one entry in the `jinn.execution.v1` wrapper
7
+ * envelope's `artifacts[]`. Carrier invariant by provenance kind:
8
+ * **imported** (seeds) publish ALONGSIDE the seeded layer-1 trace envelope
9
+ * (never instead of it); **distilled** skills have no trace of their own —
10
+ * their evidence is the referenced layer-1 envelopes in `sourceEnvelopeCids` —
11
+ * so they publish as a skill-only wrapper (`publishSkill()`,
12
+ * packages/layer/src/publish-skill.ts, DR-2026-07-06).
13
+ * Access/pricing come from the enclosing Artifact
14
+ * entry (client/src/types/envelope.ts ArtifactSchema: sha256,
15
+ * access.endpoint, access.priceUsdc, metadata.tags).
16
+ *
17
+ * Frozen-caps review (AC3, additive): this schema is a NEW artifact payload
18
+ * type. It does not touch the frozen layer-1 evidence envelope
19
+ * (jinn.trace-envelope.v0 — packages/core/src/envelope.ts,
20
+ * caps in packages/layer/docs/envelope-v0.md) and requires no
21
+ * change to the jinn.execution.v1 wrapper, whose artifacts[] already accepts
22
+ * any artifactType string. Companion-file content lives here, free of the
23
+ * trace envelope's 16 KiB step-attribute cap, under its own 1 MiB total cap.
24
+ *
25
+ * Precedent: client/src/trajectory/harness-bundle-schema.ts.
26
+ */
27
+ export declare const SKILL_ARTIFACT_TYPE: "jinn.skill.v1";
28
+ /** Max companion files per skill. */
29
+ export declare const MAX_SKILL_FILES = 64;
30
+ /** Max total decoded bytes (skillMd + all companion files): 1 MiB. */
31
+ export declare const MAX_SKILL_TOTAL_DECODED_BYTES: number;
32
+ export declare const SkillCompanionFileSchema: z.ZodObject<{
33
+ path: z.ZodEffects<z.ZodString, string, string>;
34
+ contentBase64: z.ZodString;
35
+ sha256: z.ZodString;
36
+ }, "strip", z.ZodTypeAny, {
37
+ path: string;
38
+ sha256: string;
39
+ contentBase64: string;
40
+ }, {
41
+ path: string;
42
+ sha256: string;
43
+ contentBase64: string;
44
+ }>;
45
+ export declare const SkillProvenanceSchema: z.ZodObject<{
46
+ kind: z.ZodEnum<["imported", "distilled"]>;
47
+ /**
48
+ * Envelope CIDs the skill was distilled from ([] for seed imports).
49
+ * The "distilled from N traces" count is this array's length — never
50
+ * stored separately (anti-drift).
51
+ */
52
+ sourceEnvelopeCids: z.ZodArray<z.ZodString, "many">;
53
+ operator: z.ZodObject<{
54
+ safeAddress: z.ZodString;
55
+ }, "strip", z.ZodTypeAny, {
56
+ safeAddress: string;
57
+ }, {
58
+ safeAddress: string;
59
+ }>;
60
+ solverType: z.ZodOptional<z.ZodString>;
61
+ /** Seed attribution, mirroring the seeded trace's `seed.attribution`. */
62
+ seed: z.ZodOptional<z.ZodObject<{
63
+ skill: z.ZodString;
64
+ source: z.ZodString;
65
+ licence: z.ZodNullable<z.ZodString>;
66
+ }, "strip", z.ZodTypeAny, {
67
+ source: string;
68
+ skill: string;
69
+ licence: string | null;
70
+ }, {
71
+ source: string;
72
+ skill: string;
73
+ licence: string | null;
74
+ }>>;
75
+ /**
76
+ * Success→strategic-pattern, failure→lesson, both-polarity→contrastive
77
+ * (spec §7, D10 + v0.5), or cross-instance corroboration→cross-instance
78
+ * (stage-2 meta-distill). `contrastive` and `cross-instance` are additive
79
+ * enum values: strict consumers (`extractSkill`) reject them until upgraded
80
+ * — acceptable at testnet volume, named in the spec.
81
+ */
82
+ skillKind: z.ZodOptional<z.ZodEnum<["strategic-pattern", "failure-lesson", "contrastive", "cross-instance"]>>;
83
+ /** SHA-256 of the exact distill prompt that produced the skill (auditability, D4). */
84
+ distillPromptSha256: z.ZodOptional<z.ZodString>;
85
+ /** Task-distribution the skill targets (e.g. 'coding'). */
86
+ distribution: z.ZodOptional<z.ZodString>;
87
+ /** Verifiability tier of the source evidence (e.g. 'evaluator-verified'). */
88
+ verifiabilityTier: z.ZodOptional<z.ZodString>;
89
+ /**
90
+ * The model that ran distillation (spec §5, v0.5). Distillation quality is
91
+ * model-sensitive; recording it makes a skill's quality auditable.
92
+ */
93
+ distillModel: z.ZodOptional<z.ZodString>;
94
+ /**
95
+ * Deterministic `ceil(utf8 chars / 4)` token estimates of the distiller
96
+ * input and the emitted body (spec §5, v0.5). The pair records the
97
+ * compression ratio (SkillRL operates at 10–20×); an auditable estimate
98
+ * serves that purpose better than an unreproducible exact count (the LLM
99
+ * port reports no usage).
100
+ */
101
+ evidenceTokens: z.ZodOptional<z.ZodNumber>;
102
+ skillTokens: z.ZodOptional<z.ZodNumber>;
103
+ /**
104
+ * Envelope/manifest CID of a prior skill record this one replaces — the same
105
+ * identity space as `sourceEnvelopeCids` and a search-hit `ref`. Honored at
106
+ * read time ONLY when this record's operator matches the superseded record's
107
+ * operator (cross-operator supersedes are ignored); see the read-path head
108
+ * resolver in packages/layer/src/consume.ts.
109
+ */
110
+ supersedes: z.ZodOptional<z.ZodString>;
111
+ /**
112
+ * Pure retirement marker: retires this record's `supersedes` target with no
113
+ * replacement and hides this record itself from discovery. A deprecation
114
+ * record carries no successor skill content.
115
+ */
116
+ deprecates: z.ZodOptional<z.ZodBoolean>;
117
+ }, "strip", z.ZodTypeAny, {
118
+ kind: "imported" | "distilled";
119
+ sourceEnvelopeCids: string[];
120
+ operator: {
121
+ safeAddress: string;
122
+ };
123
+ verifiabilityTier?: string | undefined;
124
+ solverType?: string | undefined;
125
+ seed?: {
126
+ source: string;
127
+ skill: string;
128
+ licence: string | null;
129
+ } | undefined;
130
+ skillKind?: "strategic-pattern" | "failure-lesson" | "contrastive" | "cross-instance" | undefined;
131
+ distillPromptSha256?: string | undefined;
132
+ distribution?: string | undefined;
133
+ distillModel?: string | undefined;
134
+ evidenceTokens?: number | undefined;
135
+ skillTokens?: number | undefined;
136
+ supersedes?: string | undefined;
137
+ deprecates?: boolean | undefined;
138
+ }, {
139
+ kind: "imported" | "distilled";
140
+ sourceEnvelopeCids: string[];
141
+ operator: {
142
+ safeAddress: string;
143
+ };
144
+ verifiabilityTier?: string | undefined;
145
+ solverType?: string | undefined;
146
+ seed?: {
147
+ source: string;
148
+ skill: string;
149
+ licence: string | null;
150
+ } | undefined;
151
+ skillKind?: "strategic-pattern" | "failure-lesson" | "contrastive" | "cross-instance" | undefined;
152
+ distillPromptSha256?: string | undefined;
153
+ distribution?: string | undefined;
154
+ distillModel?: string | undefined;
155
+ evidenceTokens?: number | undefined;
156
+ skillTokens?: number | undefined;
157
+ supersedes?: string | undefined;
158
+ deprecates?: boolean | undefined;
159
+ }>;
160
+ export declare const SkillArtifactV1Schema: z.ZodEffects<z.ZodObject<{
161
+ schemaVersion: z.ZodLiteral<"jinn.skill.v1">;
162
+ skill: z.ZodObject<{
163
+ name: z.ZodString;
164
+ description: z.ZodOptional<z.ZodString>;
165
+ skillMd: z.ZodString;
166
+ }, "strip", z.ZodTypeAny, {
167
+ name: string;
168
+ skillMd: string;
169
+ description?: string | undefined;
170
+ }, {
171
+ name: string;
172
+ skillMd: string;
173
+ description?: string | undefined;
174
+ }>;
175
+ files: z.ZodArray<z.ZodObject<{
176
+ path: z.ZodEffects<z.ZodString, string, string>;
177
+ contentBase64: z.ZodString;
178
+ sha256: z.ZodString;
179
+ }, "strip", z.ZodTypeAny, {
180
+ path: string;
181
+ sha256: string;
182
+ contentBase64: string;
183
+ }, {
184
+ path: string;
185
+ sha256: string;
186
+ contentBase64: string;
187
+ }>, "many">;
188
+ provenance: z.ZodObject<{
189
+ kind: z.ZodEnum<["imported", "distilled"]>;
190
+ /**
191
+ * Envelope CIDs the skill was distilled from ([] for seed imports).
192
+ * The "distilled from N traces" count is this array's length — never
193
+ * stored separately (anti-drift).
194
+ */
195
+ sourceEnvelopeCids: z.ZodArray<z.ZodString, "many">;
196
+ operator: z.ZodObject<{
197
+ safeAddress: z.ZodString;
198
+ }, "strip", z.ZodTypeAny, {
199
+ safeAddress: string;
200
+ }, {
201
+ safeAddress: string;
202
+ }>;
203
+ solverType: z.ZodOptional<z.ZodString>;
204
+ /** Seed attribution, mirroring the seeded trace's `seed.attribution`. */
205
+ seed: z.ZodOptional<z.ZodObject<{
206
+ skill: z.ZodString;
207
+ source: z.ZodString;
208
+ licence: z.ZodNullable<z.ZodString>;
209
+ }, "strip", z.ZodTypeAny, {
210
+ source: string;
211
+ skill: string;
212
+ licence: string | null;
213
+ }, {
214
+ source: string;
215
+ skill: string;
216
+ licence: string | null;
217
+ }>>;
218
+ /**
219
+ * Success→strategic-pattern, failure→lesson, both-polarity→contrastive
220
+ * (spec §7, D10 + v0.5), or cross-instance corroboration→cross-instance
221
+ * (stage-2 meta-distill). `contrastive` and `cross-instance` are additive
222
+ * enum values: strict consumers (`extractSkill`) reject them until upgraded
223
+ * — acceptable at testnet volume, named in the spec.
224
+ */
225
+ skillKind: z.ZodOptional<z.ZodEnum<["strategic-pattern", "failure-lesson", "contrastive", "cross-instance"]>>;
226
+ /** SHA-256 of the exact distill prompt that produced the skill (auditability, D4). */
227
+ distillPromptSha256: z.ZodOptional<z.ZodString>;
228
+ /** Task-distribution the skill targets (e.g. 'coding'). */
229
+ distribution: z.ZodOptional<z.ZodString>;
230
+ /** Verifiability tier of the source evidence (e.g. 'evaluator-verified'). */
231
+ verifiabilityTier: z.ZodOptional<z.ZodString>;
232
+ /**
233
+ * The model that ran distillation (spec §5, v0.5). Distillation quality is
234
+ * model-sensitive; recording it makes a skill's quality auditable.
235
+ */
236
+ distillModel: z.ZodOptional<z.ZodString>;
237
+ /**
238
+ * Deterministic `ceil(utf8 chars / 4)` token estimates of the distiller
239
+ * input and the emitted body (spec §5, v0.5). The pair records the
240
+ * compression ratio (SkillRL operates at 10–20×); an auditable estimate
241
+ * serves that purpose better than an unreproducible exact count (the LLM
242
+ * port reports no usage).
243
+ */
244
+ evidenceTokens: z.ZodOptional<z.ZodNumber>;
245
+ skillTokens: z.ZodOptional<z.ZodNumber>;
246
+ /**
247
+ * Envelope/manifest CID of a prior skill record this one replaces — the same
248
+ * identity space as `sourceEnvelopeCids` and a search-hit `ref`. Honored at
249
+ * read time ONLY when this record's operator matches the superseded record's
250
+ * operator (cross-operator supersedes are ignored); see the read-path head
251
+ * resolver in packages/layer/src/consume.ts.
252
+ */
253
+ supersedes: z.ZodOptional<z.ZodString>;
254
+ /**
255
+ * Pure retirement marker: retires this record's `supersedes` target with no
256
+ * replacement and hides this record itself from discovery. A deprecation
257
+ * record carries no successor skill content.
258
+ */
259
+ deprecates: z.ZodOptional<z.ZodBoolean>;
260
+ }, "strip", z.ZodTypeAny, {
261
+ kind: "imported" | "distilled";
262
+ sourceEnvelopeCids: string[];
263
+ operator: {
264
+ safeAddress: string;
265
+ };
266
+ verifiabilityTier?: string | undefined;
267
+ solverType?: string | undefined;
268
+ seed?: {
269
+ source: string;
270
+ skill: string;
271
+ licence: string | null;
272
+ } | undefined;
273
+ skillKind?: "strategic-pattern" | "failure-lesson" | "contrastive" | "cross-instance" | undefined;
274
+ distillPromptSha256?: string | undefined;
275
+ distribution?: string | undefined;
276
+ distillModel?: string | undefined;
277
+ evidenceTokens?: number | undefined;
278
+ skillTokens?: number | undefined;
279
+ supersedes?: string | undefined;
280
+ deprecates?: boolean | undefined;
281
+ }, {
282
+ kind: "imported" | "distilled";
283
+ sourceEnvelopeCids: string[];
284
+ operator: {
285
+ safeAddress: string;
286
+ };
287
+ verifiabilityTier?: string | undefined;
288
+ solverType?: string | undefined;
289
+ seed?: {
290
+ source: string;
291
+ skill: string;
292
+ licence: string | null;
293
+ } | undefined;
294
+ skillKind?: "strategic-pattern" | "failure-lesson" | "contrastive" | "cross-instance" | undefined;
295
+ distillPromptSha256?: string | undefined;
296
+ distribution?: string | undefined;
297
+ distillModel?: string | undefined;
298
+ evidenceTokens?: number | undefined;
299
+ skillTokens?: number | undefined;
300
+ supersedes?: string | undefined;
301
+ deprecates?: boolean | undefined;
302
+ }>;
303
+ }, "strip", z.ZodTypeAny, {
304
+ schemaVersion: "jinn.skill.v1";
305
+ provenance: {
306
+ kind: "imported" | "distilled";
307
+ sourceEnvelopeCids: string[];
308
+ operator: {
309
+ safeAddress: string;
310
+ };
311
+ verifiabilityTier?: string | undefined;
312
+ solverType?: string | undefined;
313
+ seed?: {
314
+ source: string;
315
+ skill: string;
316
+ licence: string | null;
317
+ } | undefined;
318
+ skillKind?: "strategic-pattern" | "failure-lesson" | "contrastive" | "cross-instance" | undefined;
319
+ distillPromptSha256?: string | undefined;
320
+ distribution?: string | undefined;
321
+ distillModel?: string | undefined;
322
+ evidenceTokens?: number | undefined;
323
+ skillTokens?: number | undefined;
324
+ supersedes?: string | undefined;
325
+ deprecates?: boolean | undefined;
326
+ };
327
+ skill: {
328
+ name: string;
329
+ skillMd: string;
330
+ description?: string | undefined;
331
+ };
332
+ files: {
333
+ path: string;
334
+ sha256: string;
335
+ contentBase64: string;
336
+ }[];
337
+ }, {
338
+ schemaVersion: "jinn.skill.v1";
339
+ provenance: {
340
+ kind: "imported" | "distilled";
341
+ sourceEnvelopeCids: string[];
342
+ operator: {
343
+ safeAddress: string;
344
+ };
345
+ verifiabilityTier?: string | undefined;
346
+ solverType?: string | undefined;
347
+ seed?: {
348
+ source: string;
349
+ skill: string;
350
+ licence: string | null;
351
+ } | undefined;
352
+ skillKind?: "strategic-pattern" | "failure-lesson" | "contrastive" | "cross-instance" | undefined;
353
+ distillPromptSha256?: string | undefined;
354
+ distribution?: string | undefined;
355
+ distillModel?: string | undefined;
356
+ evidenceTokens?: number | undefined;
357
+ skillTokens?: number | undefined;
358
+ supersedes?: string | undefined;
359
+ deprecates?: boolean | undefined;
360
+ };
361
+ skill: {
362
+ name: string;
363
+ skillMd: string;
364
+ description?: string | undefined;
365
+ };
366
+ files: {
367
+ path: string;
368
+ sha256: string;
369
+ contentBase64: string;
370
+ }[];
371
+ }>, {
372
+ schemaVersion: "jinn.skill.v1";
373
+ provenance: {
374
+ kind: "imported" | "distilled";
375
+ sourceEnvelopeCids: string[];
376
+ operator: {
377
+ safeAddress: string;
378
+ };
379
+ verifiabilityTier?: string | undefined;
380
+ solverType?: string | undefined;
381
+ seed?: {
382
+ source: string;
383
+ skill: string;
384
+ licence: string | null;
385
+ } | undefined;
386
+ skillKind?: "strategic-pattern" | "failure-lesson" | "contrastive" | "cross-instance" | undefined;
387
+ distillPromptSha256?: string | undefined;
388
+ distribution?: string | undefined;
389
+ distillModel?: string | undefined;
390
+ evidenceTokens?: number | undefined;
391
+ skillTokens?: number | undefined;
392
+ supersedes?: string | undefined;
393
+ deprecates?: boolean | undefined;
394
+ };
395
+ skill: {
396
+ name: string;
397
+ skillMd: string;
398
+ description?: string | undefined;
399
+ };
400
+ files: {
401
+ path: string;
402
+ sha256: string;
403
+ contentBase64: string;
404
+ }[];
405
+ }, {
406
+ schemaVersion: "jinn.skill.v1";
407
+ provenance: {
408
+ kind: "imported" | "distilled";
409
+ sourceEnvelopeCids: string[];
410
+ operator: {
411
+ safeAddress: string;
412
+ };
413
+ verifiabilityTier?: string | undefined;
414
+ solverType?: string | undefined;
415
+ seed?: {
416
+ source: string;
417
+ skill: string;
418
+ licence: string | null;
419
+ } | undefined;
420
+ skillKind?: "strategic-pattern" | "failure-lesson" | "contrastive" | "cross-instance" | undefined;
421
+ distillPromptSha256?: string | undefined;
422
+ distribution?: string | undefined;
423
+ distillModel?: string | undefined;
424
+ evidenceTokens?: number | undefined;
425
+ skillTokens?: number | undefined;
426
+ supersedes?: string | undefined;
427
+ deprecates?: boolean | undefined;
428
+ };
429
+ skill: {
430
+ name: string;
431
+ skillMd: string;
432
+ description?: string | undefined;
433
+ };
434
+ files: {
435
+ path: string;
436
+ sha256: string;
437
+ contentBase64: string;
438
+ }[];
439
+ }>;
440
+ export type SkillCompanionFile = z.infer<typeof SkillCompanionFileSchema>;
441
+ export type SkillProvenance = z.infer<typeof SkillProvenanceSchema>;
442
+ export type SkillArtifactV1 = z.infer<typeof SkillArtifactV1Schema>;
@@ -0,0 +1,136 @@
1
+ import { z } from 'zod/v3';
2
+ /**
3
+ * jinn.skill.v1 — first-class skill artifact (issue #1394).
4
+ *
5
+ * A skill (SKILL.md + optional companion files + machine-readable
6
+ * provenance) carried as one entry in the `jinn.execution.v1` wrapper
7
+ * envelope's `artifacts[]`. Carrier invariant by provenance kind:
8
+ * **imported** (seeds) publish ALONGSIDE the seeded layer-1 trace envelope
9
+ * (never instead of it); **distilled** skills have no trace of their own —
10
+ * their evidence is the referenced layer-1 envelopes in `sourceEnvelopeCids` —
11
+ * so they publish as a skill-only wrapper (`publishSkill()`,
12
+ * packages/layer/src/publish-skill.ts, DR-2026-07-06).
13
+ * Access/pricing come from the enclosing Artifact
14
+ * entry (client/src/types/envelope.ts ArtifactSchema: sha256,
15
+ * access.endpoint, access.priceUsdc, metadata.tags).
16
+ *
17
+ * Frozen-caps review (AC3, additive): this schema is a NEW artifact payload
18
+ * type. It does not touch the frozen layer-1 evidence envelope
19
+ * (jinn.trace-envelope.v0 — packages/core/src/envelope.ts,
20
+ * caps in packages/layer/docs/envelope-v0.md) and requires no
21
+ * change to the jinn.execution.v1 wrapper, whose artifacts[] already accepts
22
+ * any artifactType string. Companion-file content lives here, free of the
23
+ * trace envelope's 16 KiB step-attribute cap, under its own 1 MiB total cap.
24
+ *
25
+ * Precedent: client/src/trajectory/harness-bundle-schema.ts.
26
+ */
27
+ export const SKILL_ARTIFACT_TYPE = 'jinn.skill.v1';
28
+ /** Max companion files per skill. */
29
+ export const MAX_SKILL_FILES = 64;
30
+ /** Max total decoded bytes (skillMd + all companion files): 1 MiB. */
31
+ export const MAX_SKILL_TOTAL_DECODED_BYTES = 1024 * 1024;
32
+ const HexAddressSchema = z.string().regex(/^0x[0-9a-fA-F]*$/);
33
+ /**
34
+ * Relative, traversal-free POSIX path — this is written to disk on install.
35
+ * Backslashes are rejected outright: on Windows `path.join` treats `\` as a
36
+ * separator, so a `..\` segment would bypass the '/'-split traversal check.
37
+ */
38
+ const CompanionPathSchema = z
39
+ .string()
40
+ .min(1)
41
+ .refine((p) => !p.includes('\\') &&
42
+ !p.startsWith('/') &&
43
+ !/^[A-Za-z]:/.test(p) &&
44
+ !p.split('/').includes('..') &&
45
+ !p.split('/').includes(''), { message: 'companion file path must be a relative, traversal-free POSIX path' });
46
+ export const SkillCompanionFileSchema = z.object({
47
+ path: CompanionPathSchema,
48
+ contentBase64: z.string(),
49
+ sha256: z.string().regex(/^[0-9a-f]{64}$/),
50
+ });
51
+ export const SkillProvenanceSchema = z.object({
52
+ kind: z.enum(['imported', 'distilled']),
53
+ /**
54
+ * Envelope CIDs the skill was distilled from ([] for seed imports).
55
+ * The "distilled from N traces" count is this array's length — never
56
+ * stored separately (anti-drift).
57
+ */
58
+ sourceEnvelopeCids: z.array(z.string().min(1)),
59
+ operator: z.object({ safeAddress: HexAddressSchema }),
60
+ solverType: z.string().min(1).optional(),
61
+ /** Seed attribution, mirroring the seeded trace's `seed.attribution`. */
62
+ seed: z
63
+ .object({
64
+ skill: z.string().min(1),
65
+ source: z.string().min(1),
66
+ licence: z.string().nullable(),
67
+ })
68
+ .optional(),
69
+ // --- distilled-skill fields (DR-2026-07-06, additive; producer is
70
+ // publishSkill() in packages/layer/src/publish-skill.ts) ---
71
+ /**
72
+ * Success→strategic-pattern, failure→lesson, both-polarity→contrastive
73
+ * (spec §7, D10 + v0.5), or cross-instance corroboration→cross-instance
74
+ * (stage-2 meta-distill). `contrastive` and `cross-instance` are additive
75
+ * enum values: strict consumers (`extractSkill`) reject them until upgraded
76
+ * — acceptable at testnet volume, named in the spec.
77
+ */
78
+ skillKind: z.enum(['strategic-pattern', 'failure-lesson', 'contrastive', 'cross-instance']).optional(),
79
+ /** SHA-256 of the exact distill prompt that produced the skill (auditability, D4). */
80
+ distillPromptSha256: z
81
+ .string()
82
+ .regex(/^[0-9a-f]{64}$/)
83
+ .optional(),
84
+ /** Task-distribution the skill targets (e.g. 'coding'). */
85
+ distribution: z.string().min(1).optional(),
86
+ /** Verifiability tier of the source evidence (e.g. 'evaluator-verified'). */
87
+ verifiabilityTier: z.string().min(1).optional(),
88
+ /**
89
+ * The model that ran distillation (spec §5, v0.5). Distillation quality is
90
+ * model-sensitive; recording it makes a skill's quality auditable.
91
+ */
92
+ distillModel: z.string().min(1).optional(),
93
+ /**
94
+ * Deterministic `ceil(utf8 chars / 4)` token estimates of the distiller
95
+ * input and the emitted body (spec §5, v0.5). The pair records the
96
+ * compression ratio (SkillRL operates at 10–20×); an auditable estimate
97
+ * serves that purpose better than an unreproducible exact count (the LLM
98
+ * port reports no usage).
99
+ */
100
+ evidenceTokens: z.number().int().nonnegative().optional(),
101
+ skillTokens: z.number().int().nonnegative().optional(),
102
+ // --- supersede lineage (issue #1462, additive) ---
103
+ /**
104
+ * Envelope/manifest CID of a prior skill record this one replaces — the same
105
+ * identity space as `sourceEnvelopeCids` and a search-hit `ref`. Honored at
106
+ * read time ONLY when this record's operator matches the superseded record's
107
+ * operator (cross-operator supersedes are ignored); see the read-path head
108
+ * resolver in packages/layer/src/consume.ts.
109
+ */
110
+ supersedes: z.string().min(1).optional(),
111
+ /**
112
+ * Pure retirement marker: retires this record's `supersedes` target with no
113
+ * replacement and hides this record itself from discovery. A deprecation
114
+ * record carries no successor skill content.
115
+ */
116
+ deprecates: z.boolean().optional(),
117
+ });
118
+ /** Decoded size of a base64 string without decoding it. */
119
+ function base64DecodedBytes(b64) {
120
+ const padding = b64.endsWith('==') ? 2 : b64.endsWith('=') ? 1 : 0;
121
+ return Math.max(0, Math.floor((b64.length * 3) / 4) - padding);
122
+ }
123
+ export const SkillArtifactV1Schema = z
124
+ .object({
125
+ schemaVersion: z.literal(SKILL_ARTIFACT_TYPE),
126
+ skill: z.object({
127
+ name: z.string().min(1),
128
+ description: z.string().optional(),
129
+ skillMd: z.string().min(1),
130
+ }),
131
+ files: z.array(SkillCompanionFileSchema).max(MAX_SKILL_FILES),
132
+ provenance: SkillProvenanceSchema,
133
+ })
134
+ .refine((a) => new TextEncoder().encode(a.skill.skillMd).length +
135
+ a.files.reduce((n, f) => n + base64DecodedBytes(f.contentBase64), 0) <=
136
+ MAX_SKILL_TOTAL_DECODED_BYTES, { message: 'skill artifact exceeds the 1 MiB total decoded-content cap' });
@@ -0,0 +1,18 @@
1
+ /**
2
+ * In-run per-span hash chain.
3
+ *
4
+ * Scope: §3.1 trajectory-signing-granularity row — "each span carries
5
+ * jinn.prevSpanHash linking to the previous span's hash; first span
6
+ * links to a run-start genesis value derived from envelope task CID."
7
+ *
8
+ * Motivation: a crashed run that failed to upload the signed trajectory
9
+ * blob still produces a verifiable-as-prefix trace if spans are recovered
10
+ * elsewhere (enclave memory dump, challenger capture). Partial authenticity
11
+ * is not zero.
12
+ */
13
+ import type { Span } from './schema.js';
14
+ export type Hex = `0x${string}`;
15
+ /** Genesis value for the chain — keccak256(JCS({runStart: taskCid})). */
16
+ export declare function computeGenesisHash(taskCid: string): Hex;
17
+ /** Hash of a finalized span, to be set as jinn.prevSpanHash on the next one. */
18
+ export declare function computePrevSpanHash(span: Span): Hex;