@zelari/core 1.49.0 → 2.0.0-alpha.2

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 (105) hide show
  1. package/dist/experimental.d.ts +17 -0
  2. package/dist/experimental.d.ts.map +1 -0
  3. package/dist/experimental.js +31 -0
  4. package/dist/experimental.js.map +1 -0
  5. package/dist/index.d.ts +5 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +10 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/mission/index.d.ts +5 -0
  10. package/dist/mission/index.d.ts.map +1 -0
  11. package/dist/mission/index.js +5 -0
  12. package/dist/mission/index.js.map +1 -0
  13. package/dist/mission/missionState.d.ts +37 -0
  14. package/dist/mission/missionState.d.ts.map +1 -0
  15. package/dist/mission/missionState.js +61 -0
  16. package/dist/mission/missionState.js.map +1 -0
  17. package/dist/runtime/executionContext.d.ts +46 -0
  18. package/dist/runtime/executionContext.d.ts.map +1 -0
  19. package/dist/runtime/executionContext.js +63 -0
  20. package/dist/runtime/executionContext.js.map +1 -0
  21. package/dist/runtime/index.d.ts +10 -0
  22. package/dist/runtime/index.d.ts.map +1 -0
  23. package/dist/runtime/index.js +10 -0
  24. package/dist/runtime/index.js.map +1 -0
  25. package/dist/runtime/memoryProviders.d.ts +27 -0
  26. package/dist/runtime/memoryProviders.d.ts.map +1 -0
  27. package/dist/runtime/memoryProviders.js +64 -0
  28. package/dist/runtime/memoryProviders.js.map +1 -0
  29. package/dist/runtime/nodeProviders.d.ts +21 -0
  30. package/dist/runtime/nodeProviders.d.ts.map +1 -0
  31. package/dist/runtime/nodeProviders.js +138 -0
  32. package/dist/runtime/nodeProviders.js.map +1 -0
  33. package/dist/runtime/profiles.d.ts +44 -0
  34. package/dist/runtime/profiles.d.ts.map +1 -0
  35. package/dist/runtime/profiles.js +91 -0
  36. package/dist/runtime/profiles.js.map +1 -0
  37. package/dist/runtime/providers.d.ts +85 -0
  38. package/dist/runtime/providers.d.ts.map +1 -0
  39. package/dist/runtime/providers.js +58 -0
  40. package/dist/runtime/providers.js.map +1 -0
  41. package/dist/runtime/worktreeWorkspace.d.ts +38 -0
  42. package/dist/runtime/worktreeWorkspace.d.ts.map +1 -0
  43. package/dist/runtime/worktreeWorkspace.js +80 -0
  44. package/dist/runtime/worktreeWorkspace.js.map +1 -0
  45. package/dist/session/exportSession.d.ts +31 -0
  46. package/dist/session/exportSession.d.ts.map +1 -0
  47. package/dist/session/exportSession.js +37 -0
  48. package/dist/session/exportSession.js.map +1 -0
  49. package/dist/session/index.d.ts +15 -0
  50. package/dist/session/index.d.ts.map +1 -0
  51. package/dist/session/index.js +15 -0
  52. package/dist/session/index.js.map +1 -0
  53. package/dist/session/lineage.d.ts +38 -0
  54. package/dist/session/lineage.d.ts.map +1 -0
  55. package/dist/session/lineage.js +69 -0
  56. package/dist/session/lineage.js.map +1 -0
  57. package/dist/session/modelSurface.d.ts +43 -0
  58. package/dist/session/modelSurface.d.ts.map +1 -0
  59. package/dist/session/modelSurface.js +96 -0
  60. package/dist/session/modelSurface.js.map +1 -0
  61. package/dist/session/replay.d.ts +61 -0
  62. package/dist/session/replay.d.ts.map +1 -0
  63. package/dist/session/replay.js +137 -0
  64. package/dist/session/replay.js.map +1 -0
  65. package/dist/session/store.d.ts +60 -0
  66. package/dist/session/store.d.ts.map +1 -0
  67. package/dist/session/store.js +117 -0
  68. package/dist/session/store.js.map +1 -0
  69. package/dist/session/types.d.ts +85 -0
  70. package/dist/session/types.d.ts.map +1 -0
  71. package/dist/session/types.js +62 -0
  72. package/dist/session/types.js.map +1 -0
  73. package/dist/session/writer.d.ts +44 -0
  74. package/dist/session/writer.d.ts.map +1 -0
  75. package/dist/session/writer.js +114 -0
  76. package/dist/session/writer.js.map +1 -0
  77. package/dist/verification/completionPolicy.d.ts +33 -0
  78. package/dist/verification/completionPolicy.d.ts.map +1 -0
  79. package/dist/verification/completionPolicy.js +68 -0
  80. package/dist/verification/completionPolicy.js.map +1 -0
  81. package/dist/verification/criteriaPack.v1.d.ts +27 -0
  82. package/dist/verification/criteriaPack.v1.d.ts.map +1 -0
  83. package/dist/verification/criteriaPack.v1.js +58 -0
  84. package/dist/verification/criteriaPack.v1.js.map +1 -0
  85. package/dist/verification/engine.d.ts +38 -0
  86. package/dist/verification/engine.d.ts.map +1 -0
  87. package/dist/verification/engine.js +163 -0
  88. package/dist/verification/engine.js.map +1 -0
  89. package/dist/verification/index.d.ts +11 -0
  90. package/dist/verification/index.d.ts.map +1 -0
  91. package/dist/verification/index.js +11 -0
  92. package/dist/verification/index.js.map +1 -0
  93. package/dist/verification/metrics.d.ts +26 -0
  94. package/dist/verification/metrics.d.ts.map +1 -0
  95. package/dist/verification/metrics.js +29 -0
  96. package/dist/verification/metrics.js.map +1 -0
  97. package/dist/verification/types.d.ts +161 -0
  98. package/dist/verification/types.d.ts.map +1 -0
  99. package/dist/verification/types.js +92 -0
  100. package/dist/verification/types.js.map +1 -0
  101. package/dist/verification/verifier.d.ts +133 -0
  102. package/dist/verification/verifier.d.ts.map +1 -0
  103. package/dist/verification/verifier.js +215 -0
  104. package/dist/verification/verifier.js.map +1 -0
  105. package/package.json +17 -1
@@ -0,0 +1,117 @@
1
+ /**
2
+ * session/store.ts — session directory management.
3
+ *
4
+ * Default location (ADR-0016 ratification): `<workspaceRoot>/.zelari/sessions/
5
+ * <sessionId>/events.jsonl`, overridable via `ZELARI_SESSIONS_DIR` or the
6
+ * explicit option. The legacy home-level sidecar remains read-only compat.
7
+ */
8
+ import { promises as fs } from 'node:fs';
9
+ import path from 'node:path';
10
+ import crypto from 'node:crypto';
11
+ import { SessionLogWriter } from './writer.js';
12
+ import { buildProjection, readSessionLog } from './replay.js';
13
+ import { ACTOR_SYSTEM } from './types.js';
14
+ export function resolveSessionsDir(options = {}) {
15
+ if (options.baseDir)
16
+ return options.baseDir;
17
+ const envDir = options.env?.ZELARI_SESSIONS_DIR ?? process.env.ZELARI_SESSIONS_DIR;
18
+ if (envDir)
19
+ return envDir;
20
+ const root = options.workspaceRoot ?? process.cwd();
21
+ return path.join(root, '.zelari', 'sessions');
22
+ }
23
+ export class SessionStore {
24
+ baseDir;
25
+ constructor(baseDir) {
26
+ this.baseDir = baseDir;
27
+ }
28
+ static withDefaults(options = {}) {
29
+ return new SessionStore(resolveSessionsDir(options));
30
+ }
31
+ get dir() {
32
+ return this.baseDir;
33
+ }
34
+ sessionDir(sessionId) {
35
+ return path.join(this.baseDir, sessionId);
36
+ }
37
+ eventsPath(sessionId) {
38
+ return path.join(this.sessionDir(sessionId), 'events.jsonl');
39
+ }
40
+ /** Create a new session and its writer; appends `session.started`. */
41
+ async create(options = {}) {
42
+ const sessionId = crypto.randomUUID();
43
+ const writer = await SessionLogWriter.open(this.sessionDir(sessionId), sessionId, 1);
44
+ await writer.append({
45
+ kind: 'session.started',
46
+ actor: ACTOR_SYSTEM,
47
+ data: {
48
+ reason: options.reason ?? 'new',
49
+ profile: options.profile,
50
+ workspace: options.workspace,
51
+ },
52
+ });
53
+ return { sessionId, writer };
54
+ }
55
+ /** Replay a session log (tolerant read). */
56
+ async read(sessionId) {
57
+ return readSessionLog(this.eventsPath(sessionId));
58
+ }
59
+ /** Materialized view of a session. */
60
+ async projection(sessionId) {
61
+ const report = await this.read(sessionId);
62
+ return buildProjection(report.events, report.issues);
63
+ }
64
+ /** Reopen a session for writing (continues seq after lastSeq). Pure: no event appended. */
65
+ async open(sessionId) {
66
+ const report = await this.read(sessionId);
67
+ if (report.events.length === 0 && report.issues.length === 0) {
68
+ throw new Error(`Session not found: ${sessionId} (${this.eventsPath(sessionId)})`);
69
+ }
70
+ const lastSeq = report.events[report.events.length - 1]?.seq ?? 0;
71
+ const writer = await SessionLogWriter.open(this.sessionDir(sessionId), sessionId, lastSeq + 1);
72
+ return { writer, report, projection: buildProjection(report.events, report.issues) };
73
+ }
74
+ async exists(sessionId) {
75
+ try {
76
+ await fs.access(this.eventsPath(sessionId));
77
+ return true;
78
+ }
79
+ catch {
80
+ return false;
81
+ }
82
+ }
83
+ /** Summaries of all stored sessions (newest first by startedAt). */
84
+ async list() {
85
+ let names;
86
+ try {
87
+ names = await fs.readdir(this.baseDir);
88
+ }
89
+ catch {
90
+ return [];
91
+ }
92
+ const summaries = [];
93
+ for (const name of names) {
94
+ const report = await readSessionLog(this.eventsPath(name));
95
+ if (report.events.length === 0 && report.issues.length === 0)
96
+ continue;
97
+ const projection = buildProjection(report.events);
98
+ summaries.push({
99
+ sessionId: name,
100
+ lastSeq: projection.lastSeq,
101
+ eventCount: projection.eventCount,
102
+ startedAt: projection.startedAt,
103
+ endedAt: projection.endedAt,
104
+ forkParent: projection.fork?.parentSessionId,
105
+ });
106
+ }
107
+ summaries.sort((a, b) => (b.startedAt ?? 0) - (a.startedAt ?? 0));
108
+ return summaries;
109
+ }
110
+ /** End a session cleanly (appends `session.ended` and releases the writer). */
111
+ async end(writer, reason = 'completed') {
112
+ const event = { kind: 'session.ended', actor: ACTOR_SYSTEM, data: { reason } };
113
+ await writer.append(event);
114
+ await writer.close();
115
+ }
116
+ }
117
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/session/store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,cAAc,EAA6C,MAAM,aAAa,CAAC;AACzG,OAAO,EAAE,YAAY,EAA0B,MAAM,YAAY,CAAC;AAWlE,MAAM,UAAU,kBAAkB,CAAC,UAA8B,EAAE;IACjE,IAAI,OAAO,CAAC,OAAO;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC;IAC5C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,mBAAmB,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;IACnF,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACpD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAChD,CAAC;AAiBD,MAAM,OAAO,YAAY;IACM;IAA7B,YAA6B,OAAe;QAAf,YAAO,GAAP,OAAO,CAAQ;IAAG,CAAC;IAEhD,MAAM,CAAC,YAAY,CAAC,UAA8B,EAAE;QAClD,OAAO,IAAI,YAAY,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC;IACvD,CAAC;IAED,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,UAAU,CAAC,SAAiB;QAC1B,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC5C,CAAC;IAED,UAAU,CAAC,SAAiB;QAC1B,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,cAAc,CAAC,CAAC;IAC/D,CAAC;IAED,sEAAsE;IACtE,KAAK,CAAC,MAAM,CAAC,UAAgC,EAAE;QAC7C,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;QACrF,MAAM,MAAM,CAAC,MAAM,CAAC;YAClB,IAAI,EAAE,iBAAiB;YACvB,KAAK,EAAE,YAAY;YACnB,IAAI,EAAE;gBACJ,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;gBAC/B,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,SAAS,EAAE,OAAO,CAAC,SAAS;aAC7B;SACF,CAAC,CAAC;QACH,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAC/B,CAAC;IAED,4CAA4C;IAC5C,KAAK,CAAC,IAAI,CAAC,SAAiB;QAC1B,OAAO,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;IACpD,CAAC;IAED,sCAAsC;IACtC,KAAK,CAAC,UAAU,CAAC,SAAiB;QAChC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC1C,OAAO,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACvD,CAAC;IAED,2FAA2F;IAC3F,KAAK,CAAC,IAAI,CAAC,SAAiB;QAC1B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC1C,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7D,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,KAAK,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACrF,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;QAClE,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC;QAC/F,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;IACvF,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,SAAiB;QAC5B,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;YAC5C,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,oEAAoE;IACpE,KAAK,CAAC,IAAI;QACR,IAAI,KAAe,CAAC;QACpB,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,SAAS,GAAuB,EAAE,CAAC;QACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YAC3D,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YACvE,MAAM,UAAU,GAAG,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAClD,SAAS,CAAC,IAAI,CAAC;gBACb,SAAS,EAAE,IAAI;gBACf,OAAO,EAAE,UAAU,CAAC,OAAO;gBAC3B,UAAU,EAAE,UAAU,CAAC,UAAU;gBACjC,SAAS,EAAE,UAAU,CAAC,SAAS;gBAC/B,OAAO,EAAE,UAAU,CAAC,OAAO;gBAC3B,UAAU,EAAE,UAAU,CAAC,IAAI,EAAE,eAAe;aAC7C,CAAC,CAAC;QACL,CAAC;QACD,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC;QAClE,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,+EAA+E;IAC/E,KAAK,CAAC,GAAG,CAAC,MAAwB,EAAE,MAAM,GAAG,WAAW;QACtD,MAAM,KAAK,GAAsB,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC;QAClG,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;CACF"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * session/types.ts — Session spine v1: envelope + event vocabulary (ADR-0016/0021).
3
+ *
4
+ * The session log is the single source of truth for what the model saw and
5
+ * what the harness did. One JSON object per line:
6
+ *
7
+ * {"schemaVersion":1,"sessionId":"…","seq":7,"ts":1755…,"kind":"tool.result",
8
+ * "actor":{"type":"agent"},"data":{…}}
9
+ *
10
+ * Invariant (P1): model-visible ⟺ logged — every kind that feeds the model
11
+ * input must appear in MODEL_SURFACE_KINDS (see modelSurface.ts). The
12
+ * vocabulary is closed: new kinds require a schema review (ADR-0021).
13
+ */
14
+ import { z } from 'zod';
15
+ /** Bump on breaking envelope/event changes; migrations documented in MIGRATION.md. */
16
+ export declare const SESSION_SCHEMA_VERSION = 1;
17
+ export declare const SessionActorSchema: z.ZodObject<{
18
+ type: z.ZodEnum<{
19
+ user: "user";
20
+ system: "system";
21
+ tool: "tool";
22
+ agent: "agent";
23
+ subagent: "subagent";
24
+ }>;
25
+ id: z.ZodOptional<z.ZodString>;
26
+ role: z.ZodOptional<z.ZodString>;
27
+ }, z.core.$strip>;
28
+ export type SessionActor = z.infer<typeof SessionActorSchema>;
29
+ /**
30
+ * Closed event vocabulary (surface + state events).
31
+ * Surface (model-visible): user.message, assistant.message, tool.call,
32
+ * tool.result, session.compacted. Everything else is state/derived.
33
+ */
34
+ export declare const SESSION_EVENT_KINDS: readonly ["session.started", "session.resumed", "session.ended", "session.forked", "user.message", "assistant.message", "tool.call", "tool.result", "context.injected", "session.compacted", "task.created", "task.updated", "kraken.task", "council.member", "mission.phase", "mission.replan", "verification.run", "note"];
35
+ export type SessionEventKind = (typeof SESSION_EVENT_KINDS)[number];
36
+ export declare const SessionEventEnvelopeSchema: z.ZodObject<{
37
+ schemaVersion: z.ZodLiteral<1>;
38
+ sessionId: z.ZodString;
39
+ seq: z.ZodNumber;
40
+ ts: z.ZodNumber;
41
+ kind: z.ZodEnum<{
42
+ note: "note";
43
+ "session.started": "session.started";
44
+ "session.resumed": "session.resumed";
45
+ "session.ended": "session.ended";
46
+ "session.forked": "session.forked";
47
+ "user.message": "user.message";
48
+ "assistant.message": "assistant.message";
49
+ "tool.call": "tool.call";
50
+ "tool.result": "tool.result";
51
+ "context.injected": "context.injected";
52
+ "session.compacted": "session.compacted";
53
+ "task.created": "task.created";
54
+ "task.updated": "task.updated";
55
+ "kraken.task": "kraken.task";
56
+ "council.member": "council.member";
57
+ "mission.phase": "mission.phase";
58
+ "mission.replan": "mission.replan";
59
+ "verification.run": "verification.run";
60
+ }>;
61
+ actor: z.ZodObject<{
62
+ type: z.ZodEnum<{
63
+ user: "user";
64
+ system: "system";
65
+ tool: "tool";
66
+ agent: "agent";
67
+ subagent: "subagent";
68
+ }>;
69
+ id: z.ZodOptional<z.ZodString>;
70
+ role: z.ZodOptional<z.ZodString>;
71
+ }, z.core.$strip>;
72
+ data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
73
+ }, z.core.$strip>;
74
+ export type SessionEventEnvelope = z.infer<typeof SessionEventEnvelopeSchema>;
75
+ /** Event payload without writer-assigned fields (seq/ts/sessionId/schemaVersion). */
76
+ export interface SessionEventInput {
77
+ kind: SessionEventKind;
78
+ actor: SessionActor;
79
+ data?: Record<string, unknown>;
80
+ }
81
+ /** Convenience actors. */
82
+ export declare const ACTOR_USER: SessionActor;
83
+ export declare const ACTOR_AGENT: SessionActor;
84
+ export declare const ACTOR_SYSTEM: SessionActor;
85
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/session/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,sFAAsF;AACtF,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,eAAO,MAAM,kBAAkB;;;;;;;;;;iBAK7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,8TAmBtB,CAAC;AACX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBASrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,qFAAqF;AACrF,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,gBAAgB,CAAC;IACvB,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,0BAA0B;AAC1B,eAAO,MAAM,UAAU,EAAE,YAA+B,CAAC;AACzD,eAAO,MAAM,WAAW,EAAE,YAAgC,CAAC;AAC3D,eAAO,MAAM,YAAY,EAAE,YAAiC,CAAC"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * session/types.ts — Session spine v1: envelope + event vocabulary (ADR-0016/0021).
3
+ *
4
+ * The session log is the single source of truth for what the model saw and
5
+ * what the harness did. One JSON object per line:
6
+ *
7
+ * {"schemaVersion":1,"sessionId":"…","seq":7,"ts":1755…,"kind":"tool.result",
8
+ * "actor":{"type":"agent"},"data":{…}}
9
+ *
10
+ * Invariant (P1): model-visible ⟺ logged — every kind that feeds the model
11
+ * input must appear in MODEL_SURFACE_KINDS (see modelSurface.ts). The
12
+ * vocabulary is closed: new kinds require a schema review (ADR-0021).
13
+ */
14
+ import { z } from 'zod';
15
+ /** Bump on breaking envelope/event changes; migrations documented in MIGRATION.md. */
16
+ export const SESSION_SCHEMA_VERSION = 1;
17
+ export const SessionActorSchema = z.object({
18
+ type: z.enum(['user', 'agent', 'system', 'subagent', 'tool']),
19
+ id: z.string().min(1).optional(),
20
+ /** Human label for display (e.g. role/persona name). */
21
+ role: z.string().min(1).optional(),
22
+ });
23
+ /**
24
+ * Closed event vocabulary (surface + state events).
25
+ * Surface (model-visible): user.message, assistant.message, tool.call,
26
+ * tool.result, session.compacted. Everything else is state/derived.
27
+ */
28
+ export const SESSION_EVENT_KINDS = [
29
+ 'session.started',
30
+ 'session.resumed',
31
+ 'session.ended',
32
+ 'session.forked',
33
+ 'user.message',
34
+ 'assistant.message',
35
+ 'tool.call',
36
+ 'tool.result',
37
+ 'context.injected',
38
+ 'session.compacted',
39
+ 'task.created',
40
+ 'task.updated',
41
+ 'kraken.task',
42
+ 'council.member',
43
+ 'mission.phase',
44
+ 'mission.replan',
45
+ 'verification.run',
46
+ 'note',
47
+ ];
48
+ export const SessionEventEnvelopeSchema = z.object({
49
+ schemaVersion: z.literal(SESSION_SCHEMA_VERSION),
50
+ sessionId: z.string().min(1),
51
+ /** Monotonic, gap-free, 1-based. Assigned by the writer after validation. */
52
+ seq: z.number().int().positive(),
53
+ ts: z.number().int().nonnegative(),
54
+ kind: z.enum(SESSION_EVENT_KINDS),
55
+ actor: SessionActorSchema,
56
+ data: z.record(z.string(), z.unknown()),
57
+ });
58
+ /** Convenience actors. */
59
+ export const ACTOR_USER = { type: 'user' };
60
+ export const ACTOR_AGENT = { type: 'agent' };
61
+ export const ACTOR_SYSTEM = { type: 'system' };
62
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/session/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,sFAAsF;AACtF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAExC,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IAC7D,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAChC,wDAAwD;IACxD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAC;AAGH;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,iBAAiB;IACjB,iBAAiB;IACjB,eAAe;IACf,gBAAgB;IAChB,cAAc;IACd,mBAAmB;IACnB,WAAW;IACX,aAAa;IACb,kBAAkB;IAClB,mBAAmB;IACnB,cAAc;IACd,cAAc;IACd,aAAa;IACb,gBAAgB;IAChB,eAAe;IACf,gBAAgB;IAChB,kBAAkB;IAClB,MAAM;CACE,CAAC;AAGX,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,aAAa,EAAE,CAAC,CAAC,OAAO,CAAC,sBAAsB,CAAC;IAChD,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5B,6EAA6E;IAC7E,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAChC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IAClC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC;IACjC,KAAK,EAAE,kBAAkB;IACzB,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;CACxC,CAAC,CAAC;AAUH,0BAA0B;AAC1B,MAAM,CAAC,MAAM,UAAU,GAAiB,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACzD,MAAM,CAAC,MAAM,WAAW,GAAiB,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3D,MAAM,CAAC,MAAM,YAAY,GAAiB,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * session/writer.ts — single-writer append-only JSONL log with ownership lock.
3
+ *
4
+ * Ownership: `<sessionDir>/writer.lock` is created with flag 'wx' holding
5
+ * `{ownership, pid, ts}`. A second writer gets SessionLogLockedError; a stale
6
+ * lock (older than staleLockMs) may be taken over. `seq` is assigned after
7
+ * Zod validation of the envelope — a rejected event never consumes a seq.
8
+ */
9
+ import { type SessionEventEnvelope, type SessionEventInput } from './types.js';
10
+ export declare class SessionLogLockedError extends Error {
11
+ readonly sessionPath: string;
12
+ readonly owner: string;
13
+ readonly code = "SESSION_LOG_LOCKED";
14
+ constructor(sessionPath: string, owner: string);
15
+ }
16
+ export interface SessionLogWriterOptions {
17
+ /** Locks older than this may be taken over. Default 10 minutes. */
18
+ staleLockMs?: number;
19
+ /** Injectable clock for tests. */
20
+ now?: () => number;
21
+ }
22
+ export declare class SessionLogWriter {
23
+ private readonly sessionId;
24
+ private readonly eventsPath;
25
+ private readonly lockPath;
26
+ private readonly ownership;
27
+ private readonly staleLockMs;
28
+ private readonly now;
29
+ private nextSeq;
30
+ private closed;
31
+ private chain;
32
+ private constructor();
33
+ /** Create the writer and acquire the ownership lock. */
34
+ static open(sessionDir: string, sessionId: string, startSeq?: number, options?: SessionLogWriterOptions): Promise<SessionLogWriter>;
35
+ get path(): string;
36
+ get currentSeq(): number;
37
+ private lockPayload;
38
+ private acquireLock;
39
+ /** Append one event; returns the validated envelope with its assigned seq. */
40
+ append(input: SessionEventInput): Promise<SessionEventEnvelope>;
41
+ /** Flush pending appends, mark closed, release the ownership lock. */
42
+ close(): Promise<void>;
43
+ }
44
+ //# sourceMappingURL=writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/session/writer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACvB,MAAM,YAAY,CAAC;AAEpB,qBAAa,qBAAsB,SAAQ,KAAK;aAG5B,WAAW,EAAE,MAAM;aACnB,KAAK,EAAE,MAAM;IAH/B,QAAQ,CAAC,IAAI,wBAAwB;gBAEnB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM;CAKhC;AAED,MAAM,WAAW,uBAAuB;IACtC,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAID,qBAAa,gBAAgB;IAYzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAX5B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuB;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAoC;IAEjD,OAAO;IAaP,wDAAwD;WAC3C,IAAI,CACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,SAAI,EACZ,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,gBAAgB,CAAC;IAO5B,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,OAAO,CAAC,WAAW;YAIL,WAAW;IAyBzB,8EAA8E;IACxE,MAAM,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAmBrE,sEAAsE;IAChE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK7B"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * session/writer.ts — single-writer append-only JSONL log with ownership lock.
3
+ *
4
+ * Ownership: `<sessionDir>/writer.lock` is created with flag 'wx' holding
5
+ * `{ownership, pid, ts}`. A second writer gets SessionLogLockedError; a stale
6
+ * lock (older than staleLockMs) may be taken over. `seq` is assigned after
7
+ * Zod validation of the envelope — a rejected event never consumes a seq.
8
+ */
9
+ import { promises as fs } from 'node:fs';
10
+ import path from 'node:path';
11
+ import crypto from 'node:crypto';
12
+ import { SESSION_SCHEMA_VERSION, SessionEventEnvelopeSchema, } from './types.js';
13
+ export class SessionLogLockedError extends Error {
14
+ sessionPath;
15
+ owner;
16
+ code = 'SESSION_LOG_LOCKED';
17
+ constructor(sessionPath, owner) {
18
+ super(`Session log is locked by another writer: ${sessionPath} (owner=${owner})`);
19
+ this.sessionPath = sessionPath;
20
+ this.owner = owner;
21
+ this.name = 'SessionLogLockedError';
22
+ }
23
+ }
24
+ const DEFAULT_STALE_LOCK_MS = 10 * 60 * 1000;
25
+ export class SessionLogWriter {
26
+ sessionId;
27
+ eventsPath;
28
+ lockPath;
29
+ ownership = crypto.randomUUID();
30
+ staleLockMs;
31
+ now;
32
+ nextSeq;
33
+ closed = false;
34
+ chain = Promise.resolve();
35
+ constructor(sessionDir, sessionId, startSeq, options) {
36
+ this.sessionId = sessionId;
37
+ this.eventsPath = path.join(sessionDir, 'events.jsonl');
38
+ this.lockPath = path.join(sessionDir, 'writer.lock');
39
+ this.nextSeq = startSeq;
40
+ this.staleLockMs = options.staleLockMs ?? DEFAULT_STALE_LOCK_MS;
41
+ this.now = options.now ?? Date.now;
42
+ }
43
+ /** Create the writer and acquire the ownership lock. */
44
+ static async open(sessionDir, sessionId, startSeq = 1, options = {}) {
45
+ const writer = new SessionLogWriter(sessionDir, sessionId, startSeq, options);
46
+ await fs.mkdir(sessionDir, { recursive: true });
47
+ await writer.acquireLock();
48
+ return writer;
49
+ }
50
+ get path() {
51
+ return this.eventsPath;
52
+ }
53
+ get currentSeq() {
54
+ return this.nextSeq - 1;
55
+ }
56
+ lockPayload() {
57
+ return JSON.stringify({ ownership: this.ownership, pid: process.pid, ts: this.now() });
58
+ }
59
+ async acquireLock() {
60
+ const payload = this.lockPayload();
61
+ try {
62
+ await fs.writeFile(this.lockPath, payload, { encoding: 'utf-8', flag: 'wx', mode: 0o644 });
63
+ return;
64
+ }
65
+ catch (err) {
66
+ if (err.code !== 'EEXIST')
67
+ throw err;
68
+ }
69
+ const existing = await fs.readFile(this.lockPath, 'utf-8').catch(() => null);
70
+ let owner = 'unknown';
71
+ let ts = 0;
72
+ if (existing) {
73
+ try {
74
+ const parsed = JSON.parse(existing);
75
+ owner = parsed.ownership ?? owner;
76
+ ts = parsed.ts ?? ts;
77
+ }
78
+ catch {
79
+ // Corrupt lock file — treat as stale.
80
+ }
81
+ }
82
+ const stale = ts > 0 && this.now() - ts > this.staleLockMs;
83
+ if (!stale)
84
+ throw new SessionLogLockedError(this.eventsPath, owner);
85
+ await fs.writeFile(this.lockPath, payload, { encoding: 'utf-8' });
86
+ }
87
+ /** Append one event; returns the validated envelope with its assigned seq. */
88
+ async append(input) {
89
+ if (this.closed)
90
+ throw new Error(`SessionLogWriter is closed (${this.eventsPath})`);
91
+ const envelope = {
92
+ schemaVersion: SESSION_SCHEMA_VERSION,
93
+ sessionId: this.sessionId,
94
+ seq: this.nextSeq,
95
+ ts: this.now(),
96
+ kind: input.kind,
97
+ actor: input.actor,
98
+ data: input.data ?? {},
99
+ };
100
+ SessionEventEnvelopeSchema.parse(envelope);
101
+ this.nextSeq += 1;
102
+ const line = JSON.stringify(envelope) + '\n';
103
+ this.chain = this.chain.then(() => fs.appendFile(this.eventsPath, line, 'utf-8'));
104
+ await this.chain;
105
+ return envelope;
106
+ }
107
+ /** Flush pending appends, mark closed, release the ownership lock. */
108
+ async close() {
109
+ await this.chain;
110
+ this.closed = true;
111
+ await fs.rm(this.lockPath, { force: true });
112
+ }
113
+ }
114
+ //# sourceMappingURL=writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writer.js","sourceRoot":"","sources":["../../src/session/writer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * verification/completionPolicy.ts — evidence-based completion gate (ADR-0023).
3
+ *
4
+ * PASS only when every required criterion has a `pass` result WITH at least
5
+ * one EvidenceRef. `fail` → REPAIR_REQUIRED (repair loop); missing/unknown
6
+ * (including "pass without evidence") → BLOCKED. A clean "done" without
7
+ * sufficient evidence is blockable by construction: unknown ≠ pass.
8
+ */
9
+ import type { Criterion, VerificationResult } from './types.js';
10
+ export type CompletionVerdict = 'PASS' | 'REPAIR_REQUIRED' | 'BLOCKED';
11
+ export interface CompletionPolicy {
12
+ mode: 'strict';
13
+ /** Criterion ids gating completion; '*' = every criterion with required:true. */
14
+ required: '*' | string[];
15
+ }
16
+ export declare const STRICT_ALL_POLICY: CompletionPolicy;
17
+ export interface UnsatisfiedCriterion {
18
+ id: string;
19
+ status: 'fail' | 'unknown' | 'missing';
20
+ reason: string;
21
+ }
22
+ export interface CompletionEvaluation {
23
+ verdict: CompletionVerdict;
24
+ satisfied: string[];
25
+ unsatisfied: UnsatisfiedCriterion[];
26
+ /** True when every required criterion passed with evidence. */
27
+ evidenceComplete: boolean;
28
+ summary: string;
29
+ }
30
+ export declare function evaluateCompletion(criteria: readonly Criterion[], results: readonly VerificationResult[], policy?: CompletionPolicy): CompletionEvaluation;
31
+ /** Alias for the strict BUILD/mission completion gate (ZELARI_STRICT_DONE). */
32
+ export declare const strictBuildGate: typeof evaluateCompletion;
33
+ //# sourceMappingURL=completionPolicy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completionPolicy.d.ts","sourceRoot":"","sources":["../../src/verification/completionPolicy.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhE,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAAC;AAEvE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,QAAQ,CAAC;IACf,iFAAiF;IACjF,QAAQ,EAAE,GAAG,GAAG,MAAM,EAAE,CAAC;CAC1B;AAED,eAAO,MAAM,iBAAiB,EAAE,gBAAoD,CAAC;AAErF,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IACvC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,WAAW,EAAE,oBAAoB,EAAE,CAAC;IACpC,+DAA+D;IAC/D,gBAAgB,EAAE,OAAO,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB;AAQD,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,SAAS,SAAS,EAAE,EAC9B,OAAO,EAAE,SAAS,kBAAkB,EAAE,EACtC,MAAM,GAAE,gBAAoC,GAC3C,oBAAoB,CAuDtB;AAED,+EAA+E;AAC/E,eAAO,MAAM,eAAe,2BAAqB,CAAC"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * verification/completionPolicy.ts — evidence-based completion gate (ADR-0023).
3
+ *
4
+ * PASS only when every required criterion has a `pass` result WITH at least
5
+ * one EvidenceRef. `fail` → REPAIR_REQUIRED (repair loop); missing/unknown
6
+ * (including "pass without evidence") → BLOCKED. A clean "done" without
7
+ * sufficient evidence is blockable by construction: unknown ≠ pass.
8
+ */
9
+ export const STRICT_ALL_POLICY = { mode: 'strict', required: '*' };
10
+ function lastResultById(results) {
11
+ const map = new Map();
12
+ for (const r of results)
13
+ map.set(r.criterionId, r);
14
+ return map;
15
+ }
16
+ export function evaluateCompletion(criteria, results, policy = STRICT_ALL_POLICY) {
17
+ const requiredIds = policy.required === '*'
18
+ ? criteria.filter((c) => c.required).map((c) => c.id)
19
+ : policy.required;
20
+ const byId = lastResultById(results);
21
+ const order = new Map(criteria.map((c, i) => [c.id, i]));
22
+ const satisfied = [];
23
+ const unsatisfied = [];
24
+ const ids = [...requiredIds].sort((a, b) => (order.get(a) ?? 0) - (order.get(b) ?? 0));
25
+ for (const id of ids) {
26
+ const result = byId.get(id);
27
+ if (!result) {
28
+ unsatisfied.push({ id, status: 'missing', reason: 'no verification result' });
29
+ continue;
30
+ }
31
+ if (result.status === 'fail') {
32
+ unsatisfied.push({ id, status: 'fail', reason: result.detail ?? 'check failed' });
33
+ continue;
34
+ }
35
+ if (result.status === 'unknown') {
36
+ unsatisfied.push({ id, status: 'unknown', reason: result.detail ?? 'not evaluable — unknown ≠ pass' });
37
+ continue;
38
+ }
39
+ if (result.evidence.length === 0) {
40
+ unsatisfied.push({
41
+ id,
42
+ status: 'unknown',
43
+ reason: 'pass without evidence refs — not acceptable for completion',
44
+ });
45
+ continue;
46
+ }
47
+ satisfied.push(id);
48
+ }
49
+ const verdict = unsatisfied.length === 0
50
+ ? 'PASS'
51
+ : unsatisfied.some((u) => u.status === 'fail')
52
+ ? 'REPAIR_REQUIRED'
53
+ : 'BLOCKED';
54
+ return {
55
+ verdict,
56
+ satisfied,
57
+ unsatisfied,
58
+ evidenceComplete: unsatisfied.length === 0,
59
+ summary: verdict === 'PASS'
60
+ ? `complete: ${satisfied.length}/${ids.length} required criteria pass with evidence`
61
+ : `incomplete (${verdict}): ${unsatisfied
62
+ .map((u) => `${u.id}=${u.status}`)
63
+ .join(', ')}`,
64
+ };
65
+ }
66
+ /** Alias for the strict BUILD/mission completion gate (ZELARI_STRICT_DONE). */
67
+ export const strictBuildGate = evaluateCompletion;
68
+ //# sourceMappingURL=completionPolicy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completionPolicy.js","sourceRoot":"","sources":["../../src/verification/completionPolicy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * verification/criteriaPack.v1.ts — Zelari Coding Criteria Pack v1.
3
+ *
4
+ * Category ids follow the plan §3A.4 taxonomy:
5
+ * correctness.{specification, observable-output, error-signals}
6
+ * quality.{scope-discipline, regression-risk}
7
+ * evidence.verification-quality
8
+ *
9
+ * Commands are repo-overridable; passing `null` leaves the criterion without
10
+ * a deterministic check → honestly `unknown` (advisory), never `pass`.
11
+ */
12
+ import type { Criterion } from './types.js';
13
+ export declare const ZELARI_CODING_PACK_ID = "zelari-coding/v1";
14
+ export interface CodingPackOptions {
15
+ typecheckCommand?: string | null;
16
+ testCommand?: string | null;
17
+ buildCommand?: string | null;
18
+ /** e.g. `git diff --name-only <base>` compared against a scope allowlist. */
19
+ scopeCommand?: string | null;
20
+ commandTimeoutMs?: number;
21
+ }
22
+ export interface CriteriaPack {
23
+ id: string;
24
+ criteria: Criterion[];
25
+ }
26
+ export declare function codingCriteriaPack(options?: CodingPackOptions): CriteriaPack;
27
+ //# sourceMappingURL=criteriaPack.v1.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"criteriaPack.v1.d.ts","sourceRoot":"","sources":["../../src/verification/criteriaPack.v1.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AAExD,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,SAAS,EAAE,CAAC;CACvB;AAED,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,iBAAsB,GAAG,YAAY,CA+ChF"}