hanoman 0.1.5 → 0.1.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hanoman",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Orchestrator + dashboard workflow docs-driven untuk sesi Claude Code / Codex",
5
5
  "type": "module",
6
6
  "repository": {
@@ -0,0 +1,43 @@
1
+ -- SPEC-408 · ADR-0090 · stempel waktu backlog: `Spec.createdAt` + `Spec.startedAt`.
2
+ --
3
+ -- SQLite melarang `ALTER TABLE … ADD COLUMN … DEFAULT CURRENT_TIMESTAMP` (default non-konstan),
4
+ -- jadi kolom ber-default waktu HARUS lewat redefinisi tabel. Redefinisi itu sekaligus tempat
5
+ -- backfill baris lama: `updatedAt` adalah satu-satunya jejak waktu yang pernah ada, dan `baseSha`
6
+ -- adalah penanda "pernah dikerjakan" yang sudah dipakai sistem (scheduler sources/backlog.ts).
7
+ -- Backfill ini APROKSIMASI dan dinyatakan terbuka di ADR-0090 — mengisinya dengan waktu migration
8
+ -- dijalankan akan membuat seluruh backlog lama tampak dibuat hari ini, yang lebih menyesatkan.
9
+ PRAGMA foreign_keys=OFF;
10
+ PRAGMA defer_foreign_keys=ON;
11
+
12
+ CREATE TABLE "new_Spec" (
13
+ "id" TEXT NOT NULL PRIMARY KEY,
14
+ "projectId" TEXT NOT NULL,
15
+ "title" TEXT NOT NULL,
16
+ "source" TEXT NOT NULL,
17
+ "stage" TEXT NOT NULL,
18
+ "priority" TEXT NOT NULL,
19
+ "author" TEXT NOT NULL,
20
+ "objective" TEXT NOT NULL,
21
+ "payload" JSONB,
22
+ "branchFrom" TEXT,
23
+ "baseSha" TEXT,
24
+ "headSha" TEXT,
25
+ "version" INTEGER NOT NULL DEFAULT 0,
26
+ "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
27
+ "startedAt" DATETIME,
28
+ "updatedAt" DATETIME NOT NULL,
29
+ CONSTRAINT "Spec_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project" ("id") ON DELETE CASCADE ON UPDATE CASCADE
30
+ );
31
+
32
+ INSERT INTO "new_Spec" ("id","projectId","title","source","stage","priority","author","objective","payload","branchFrom","baseSha","headSha","version","createdAt","startedAt","updatedAt")
33
+ SELECT "id","projectId","title","source","stage","priority","author","objective","payload","branchFrom","baseSha","headSha","version",
34
+ "updatedAt",
35
+ CASE WHEN "baseSha" IS NOT NULL THEN "updatedAt" ELSE NULL END,
36
+ "updatedAt"
37
+ FROM "Spec";
38
+
39
+ DROP TABLE "Spec";
40
+ ALTER TABLE "new_Spec" RENAME TO "Spec";
41
+
42
+ PRAGMA foreign_keys=ON;
43
+ PRAGMA defer_foreign_keys=OFF;
@@ -0,0 +1,33 @@
1
+ -- SPEC-409 · ADR-0091 · hanoman-lead: jejak keputusan + opt-in lead per project.
2
+ --
3
+ -- Ditulis tangan (bukan `migrate dev`): worktree tetangga membuat `migrate dev` me-reset DB saat
4
+ -- ada drift. Keduanya ADITIF — tak ada tabel yang diredefinisi, tak ada data yang disentuh.
5
+ --
6
+ -- `Project.leadOptIn` boleh lewat ALTER TABLE karena default-nya KONSTAN (`false`); larangan SQLite
7
+ -- hanya berlaku untuk default non-konstan seperti CURRENT_TIMESTAMP (lihat migration SPEC-408).
8
+ ALTER TABLE "Project" ADD COLUMN "leadOptIn" BOOLEAN NOT NULL DEFAULT false;
9
+
10
+ CREATE TABLE "LeadDecision" (
11
+ "id" TEXT NOT NULL PRIMARY KEY,
12
+ "projectId" TEXT NOT NULL,
13
+ "specId" TEXT,
14
+ "sessionId" TEXT,
15
+ "gate" TEXT NOT NULL,
16
+ "kind" TEXT NOT NULL,
17
+ "question" TEXT NOT NULL,
18
+ "answer" TEXT NOT NULL,
19
+ "reason" TEXT NOT NULL,
20
+ "refs" JSONB NOT NULL,
21
+ "confidence" TEXT NOT NULL,
22
+ "action" TEXT NOT NULL DEFAULT 'none',
23
+ "status" TEXT NOT NULL DEFAULT 'berlaku',
24
+ "weighty" BOOLEAN NOT NULL DEFAULT false,
25
+ "supersededById" TEXT,
26
+ "actor" TEXT NOT NULL DEFAULT 'lead',
27
+ "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
28
+ "updatedAt" DATETIME NOT NULL
29
+ );
30
+
31
+ CREATE INDEX "LeadDecision_projectId_createdAt_idx" ON "LeadDecision"("projectId", "createdAt");
32
+ CREATE INDEX "LeadDecision_specId_idx" ON "LeadDecision"("specId");
33
+ CREATE INDEX "LeadDecision_sessionId_idx" ON "LeadDecision"("sessionId");
@@ -0,0 +1,58 @@
1
+ -- SPEC-384 · ADR-0092 · cabut error monitoring (SPEC-249/254/269/271/276/296) dan cross-audit
2
+ -- (SPEC-337). Pemantauan error produksi pindah ke Uptrace; data di bawah ini tak punya pembaca
3
+ -- lagi. DESTRUKTIF & TAK BISA DIBATALKAN.
4
+ --
5
+ -- Byte source-map hidup di HANOMAN_UPLOAD_DIR dengan nama opaque `<uuid>.map` — DIREKTORI YANG
6
+ -- SAMA dengan lampiran tiket. Migration SQL tak bisa menyentuh filesystem, jadi pembersihannya
7
+ -- adalah langkah runbook manual yang dijalankan SEBELUM migration ini: baca
8
+ -- `SELECT storageKey FROM SourceMapArtifact` lalu hapus tepat berkas-berkas itu (JANGAN direktorinya
9
+ -- — lampiran tiket ikut hilang). Lihat internal/docs/operations/production.md. Melewatkannya hanya
10
+ -- menyisakan byte inert.
11
+
12
+ -- `defer_foreign_keys` wajib berpasangan dengan `foreign_keys=OFF` di sini: Spec & Ticket memegang
13
+ -- FK ke "Project", dan rebuild di bawah menjatuhkan tabel itu sebelum penggantinya bernama sama.
14
+ -- Idiom yang sama dipakai migration SPEC-408.
15
+ PRAGMA foreign_keys=OFF;
16
+ PRAGMA defer_foreign_keys=ON;
17
+
18
+ -- 1. Tabel. ErrorEvent dulu (FK → ErrorGroup).
19
+ DROP TABLE IF EXISTS "ErrorEvent";
20
+ DROP TABLE IF EXISTS "SourceMapArtifact";
21
+ DROP TABLE IF EXISTS "ErrorGroup";
22
+ DROP TABLE IF EXISTS "ProjectLink";
23
+
24
+ -- 2. Project kehilangan kolom DSN. Table rebuild (pola Prisma untuk SQLite), bukan DROP COLUMN:
25
+ -- berkas DB ini bisa dibuka SQLite versi mana pun yang dibawa instalasi npm pengguna.
26
+ CREATE TABLE "new_Project" (
27
+ "id" TEXT NOT NULL PRIMARY KEY,
28
+ "name" TEXT NOT NULL,
29
+ "desc" TEXT NOT NULL,
30
+ "kind" TEXT NOT NULL,
31
+ "repoDir" TEXT,
32
+ "gitRemote" TEXT,
33
+ "stack" TEXT NOT NULL DEFAULT '',
34
+ "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
35
+ "version" INTEGER NOT NULL DEFAULT 0,
36
+ "updatedAt" DATETIME NOT NULL,
37
+ "helpEnabled" BOOLEAN NOT NULL DEFAULT false,
38
+ "schedulerOptIn" BOOLEAN NOT NULL DEFAULT false,
39
+ "leadOptIn" BOOLEAN NOT NULL DEFAULT false
40
+ );
41
+ INSERT INTO "new_Project" ("id","name","desc","kind","repoDir","gitRemote","stack","createdAt","version","updatedAt","helpEnabled","schedulerOptIn","leadOptIn")
42
+ SELECT "id","name","desc","kind","repoDir","gitRemote","stack","createdAt","version","updatedAt","helpEnabled","schedulerOptIn","leadOptIn" FROM "Project";
43
+ DROP TABLE "Project";
44
+ ALTER TABLE "new_Project" RENAME TO "Project";
45
+
46
+ -- 3. Baris yang nilainya tak lagi sah menurut zod. Dibiarkan hidup, ia menggagalkan pembacaan
47
+ -- daftar notifikasi / backlog dengan galat parse — bukan dengan pesan yang berguna.
48
+ DELETE FROM "Notification" WHERE "type" = 'error';
49
+ -- Spec bersumber cross-audit DINORMALKAN, bukan dihapus: backlog item-nya pekerjaan nyata dengan
50
+ -- branch & dokumen; yang hilang cuma label asalnya.
51
+ UPDATE "Spec" SET "source" = 'audit' WHERE "source" = 'cross-audit';
52
+ DELETE FROM "SyncLog" WHERE "entity" = 'errorGroup';
53
+ DELETE FROM "SyncOutbox" WHERE "entity" = 'errorGroup';
54
+ DELETE FROM "SyncConflict" WHERE "entity" = 'errorGroup';
55
+ DELETE FROM "SchedulerQueueItem" WHERE "source" = 'errors';
56
+
57
+ PRAGMA foreign_keys=ON;
58
+ PRAGMA defer_foreign_keys=OFF;
@@ -18,34 +18,11 @@ model Project {
18
18
  createdAt DateTime @default(now())
19
19
  version Int @default(0) // SPEC-213 · version-stamp sync (ADR-0045)
20
20
  updatedAt DateTime @updatedAt
21
- ingestKeyHash String? // SPEC-249 · sha256(ingest key) hex; null = monitoring off. TAK PERNAH ke client.
22
- ingestKeyPrefix String? // SPEC-249 · ~12-16 char awal key untuk hint UI (bukan rahasia)
23
21
  helpEnabled Boolean @default(false) // SPEC-253 · opt-in Help Center publik
24
22
  schedulerOptIn Boolean @default(false) // SPEC-294 · ADR-0072 · opt-in scheduler otonom (LOCAL — tak masuk FIELDS sync)
23
+ leadOptIn Boolean @default(false) // SPEC-409 · ADR-0091 · opt-in hanoman-lead (LOCAL — cermin schedulerOptIn)
25
24
  specs Spec[]
26
- errorGroups ErrorGroup[]
27
25
  tickets Ticket[]
28
- sourceMaps SourceMapArtifact[] // SPEC-276 · source-map ter-upload per release (symbolication)
29
- linksOut ProjectLink[] @relation("ProjectLinkFrom") // SPEC-337 · project ini bergantung pada …
30
- linksIn ProjectLink[] @relation("ProjectLinkTo") // SPEC-337 · … yang bergantung pada project ini
31
- }
32
-
33
- // SPEC-337 · ADR-0075 · relasi integrasi/dependency BERARAH antar project: from BERGANTUNG PADA to.
34
- // LOCAL-only (tak masuk SYNCED): id cuid + unique pasangan bertabrakan saat upsert-by-id lintas device.
35
- // onUpdate: Cascade → rename project (ADR-0064) merambat gratis; tak ada ref longgar baru.
36
- model ProjectLink {
37
- id String @id @default(cuid())
38
- fromProjectId String
39
- toProjectId String
40
- kind String // api | sdk | data | event | lainnya (zLinkKind)
41
- note String @default("") // bentuk integrasinya — disalin apa adanya ke prompt sesi audit lintas
42
- createdAt DateTime @default(now())
43
- updatedAt DateTime @updatedAt
44
- from Project @relation("ProjectLinkFrom", fields: [fromProjectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
45
- to Project @relation("ProjectLinkTo", fields: [toProjectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
46
-
47
- @@unique([fromProjectId, toProjectId])
48
- @@index([toProjectId])
49
26
  }
50
27
 
51
28
  model Spec {
@@ -62,6 +39,13 @@ model Spec {
62
39
  baseSha String? // SPEC-176 · ADR-0030 · commit detach worktree sesi (nilai balik addWorktree)
63
40
  headSha String? // SPEC-176 · ADR-0030 · commit HEAD worktree di akhir sesi (sebelum removeWorktree)
64
41
  version Int @default(0) // SPEC-213 · version-stamp sync (ADR-0045)
42
+ // SPEC-408 · ADR-0090 · kapan item difilekan. Ditulis DB (@default), tak pernah oleh route —
43
+ // "dibuat" harus jadi fakta yang tak bisa diedit operator.
44
+ createdAt DateTime @default(now())
45
+ // SPEC-408 · ADR-0090 · kapan sesi PERTAMA lahir untuk item ini. Ditulis di titik cekik yang
46
+ // sama dengan `baseSha` (services/session-launch.ts); jalur RESUME (ADR-0084) sengaja tidak
47
+ // menimpanya — melanjutkan sesi bukan "mulai lagi". null = belum pernah dikerjakan.
48
+ startedAt DateTime?
65
49
  updatedAt DateTime @updatedAt
66
50
  project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
67
51
  }
@@ -302,7 +286,7 @@ model SchedulerQueueItem {
302
286
  id String @id @default(cuid())
303
287
  specId String @unique
304
288
  projectId String
305
- source String // backlog | errors | triase (asal checker)
289
+ source String // backlog | triase (asal checker) — SPEC-384 · `errors` dicabut (ADR-0092)
306
290
  priority String // tinggi | sedang | rendah (urutan drain)
307
291
  status String @default("queued") // queued | launched | done | failed
308
292
  sessionId String?
@@ -313,6 +297,39 @@ model SchedulerQueueItem {
313
297
  @@index([status])
314
298
  }
315
299
 
300
+ // SPEC-409 · ADR-0091 · jejak keputusan hanoman-lead. Data BARU yang harus bertahan (bukan nilai
301
+ // turunan seperti coverage/PRD, ADR-0011/0018): pertanyaan yang ditanyakan sesi yang sudah mati,
302
+ // dan alasan yang dipakai lead, tak bisa dihitung ulang dari sumber mana pun.
303
+ //
304
+ // LOCAL-ONLY (tak disync, cermin SessionHistory/SchedulerQueueItem): barisnya menunjuk sesi tmux &
305
+ // worktree di MESIN INI — menyiarkannya ke hub akan mengirim rujukan yang tak ada di sana. Tanpa
306
+ // `version`/notifySynced. Tak ada FK ke Project: sesi VPS memakai projectId sintetis
307
+ // (konvensi yang sama dipakai SessionResult & SessionHistory).
308
+ model LeadDecision {
309
+ id String @id @default(cuid())
310
+ projectId String
311
+ specId String?
312
+ sessionId String?
313
+ gate String // contract | detected | pulse (pintu masuk)
314
+ kind String // answer | order | collision | quality | refusal
315
+ question String
316
+ answer String
317
+ reason String
318
+ refs Json // string[] — hanya rujukan yang benar-benar ada di repo (AC-6)
319
+ confidence String // tinggi | sedang | ragu
320
+ action String @default("none") // permukaan tindakan lead (allowlist, shared/src/lead.ts)
321
+ status String @default("berlaku") // berlaku | ditimpa | dibatalkan | gagal
322
+ weighty Boolean @default(false) // memicu notifikasi (AC-25)
323
+ supersededById String? // baris yang menimpanya (jawaban operator, AC-28)
324
+ actor String @default("lead") // lead | operator — siapa yang mengeluarkan baris ini
325
+ createdAt DateTime @default(now())
326
+ updatedAt DateTime @updatedAt
327
+
328
+ @@index([projectId, createdAt])
329
+ @@index([specId])
330
+ @@index([sessionId])
331
+ }
332
+
316
333
  // SPEC-215 · ADR-0049 · LOCAL-ONLY: override config runtime (env → DB). Tak pernah disync.
317
334
  model RuntimeConfig {
318
335
  key String @id
@@ -320,68 +337,8 @@ model RuntimeConfig {
320
337
  updatedAt DateTime @updatedAt
321
338
  }
322
339
 
323
- // SPEC-249 · ADR-0060 · grup error per project (fingerprint dedup). SPEC-268/ADR-0066: agregat
324
- // grup kini tersync (version-stamp); ErrorEvent mentah tetap server-local (tak disync).
325
- model ErrorGroup {
326
- id String @id @default(cuid())
327
- projectId String
328
- fingerprint String
329
- type String
330
- message String
331
- sampleStack String?
332
- sampleFrames Json? // SPEC-276 · ADR-0070 · frame mentah sample (disymbolikasi saat display)
333
- release String? // SPEC-276 · ADR-0070 · release terakhir (korelasi build + surface di UI)
334
- environment String
335
- status String @default("new") // new | escalated | resolved
336
- count Int @default(0)
337
- firstSeenAt DateTime @default(now())
338
- lastSeenAt DateTime @default(now())
339
- specId String?
340
- createdAt DateTime @default(now())
341
- updatedAt DateTime @updatedAt
342
- version Int @default(0) // SPEC-268 · version-stamp sync (ADR-0066)
343
- project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
344
- events ErrorEvent[]
345
-
346
- @@unique([projectId, fingerprint])
347
- @@index([projectId, lastSeenAt])
348
- }
349
-
350
- // SPEC-249 · ADR-0060 · kejadian error mentah, dipangkas retensi (cap per grup + umur).
351
- model ErrorEvent {
352
- id String @id @default(cuid())
353
- groupId String
354
- projectId String
355
- type String
356
- message String
357
- stack String?
358
- frames Json? // SPEC-276 · ADR-0070 · frame terstruktur mentah dari SDK
359
- environment String
360
- release String?
361
- context Json?
362
- receivedAt DateTime @default(now())
363
- group ErrorGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
364
-
365
- @@index([groupId, receivedAt])
366
- @@index([projectId, receivedAt])
367
- }
368
340
 
369
- // SPEC-276 · ADR-0070 · source-map ter-upload per release untuk symbolication. Byte map di
370
- // HANOMAN_UPLOAD_DIR (server-local, TAK disync — cermin TicketAttachment biner & ErrorEvent).
371
- model SourceMapArtifact {
372
- id String @id @default(cuid())
373
- projectId String
374
- release String
375
- filename String // basename artifact hasil-build (mis. index-4f3a2b.js) yang dipetakan map ini
376
- debugId String?
377
- storageKey String // berkas opaque (uuid.map) di upload dir
378
- size Int
379
- createdAt DateTime @default(now())
380
- project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
381
341
 
382
- @@unique([projectId, release, filename])
383
- @@index([projectId, release])
384
- }
385
342
 
386
343
  // SPEC-253 · ADR-0062 · tiket keluhan Help Center. SPEC-268/ADR-0066: metadata tiket kini tersync
387
344
  // (version-stamp); lampiran (TicketAttachment, file biner) tetap server-local (tak disync).
@@ -396,7 +353,7 @@ model Ticket {
396
353
  status String @default("new") // new | accepted | rejected (zTicketStatus)
397
354
  accessKeyHash String @unique // sha256(kunci opaque) — lookup cek status. Plaintext hanya sekali.
398
355
  shareToken String? @unique // SPEC-293 · token bagikan link status publik (hnm_shr_…); operator → pelapor
399
- specId String? // soft-link Spec hasil promosi (cermin ErrorGroup.specId)
356
+ specId String? // soft-link Spec hasil promosi
400
357
  createdAt DateTime @default(now())
401
358
  updatedAt DateTime @updatedAt
402
359
  version Int @default(0) // SPEC-268 · version-stamp sync (ADR-0066)
@@ -411,7 +368,7 @@ model Ticket {
411
368
  model TicketAttachment {
412
369
  id String @id @default(cuid())
413
370
  ticketId String
414
- projectId String // denormal — isolasi & query murah (pola ErrorEvent.projectId)
371
+ projectId String // denormal — isolasi & query murah
415
372
  filename String // nama asli tersanitasi (display saja)
416
373
  mimeType String // image/png | image/jpeg | image/webp
417
374
  size Int