@davesheffer/hunch 1.32.8 → 1.35.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 (79) hide show
  1. package/README.md +18 -4
  2. package/dist/cli/index.js +52 -6
  3. package/dist/cli/invocation.d.ts +8 -0
  4. package/dist/cli/invocation.js +17 -10
  5. package/dist/cli/serve.js +28 -2
  6. package/dist/cli/state.d.ts +3 -0
  7. package/dist/cli/state.js +150 -0
  8. package/dist/cli/taskReport.js +52 -4
  9. package/dist/cli/update.js +5 -5
  10. package/dist/client/state.d.ts +86 -18
  11. package/dist/client/state.js +16 -2
  12. package/dist/client/stateProof.d.ts +4 -0
  13. package/dist/client/stateProof.js +17 -0
  14. package/dist/constitution/behaviorEvaluator.js +1 -1
  15. package/dist/constitution/schema.d.ts +14 -14
  16. package/dist/core/automaticReviewMemory.d.ts +5 -0
  17. package/dist/core/conventionDelivery.d.ts +8 -0
  18. package/dist/core/conventionDelivery.js +52 -0
  19. package/dist/core/fieldProvenance.d.ts +8 -0
  20. package/dist/core/fieldProvenance.js +72 -0
  21. package/dist/core/recordVisibility.d.ts +9 -0
  22. package/dist/core/recordVisibility.js +25 -0
  23. package/dist/core/stateCanonical.d.ts +3 -0
  24. package/dist/core/stateCanonical.js +34 -0
  25. package/dist/core/stateContract.d.ts +125 -10
  26. package/dist/core/stateContract.js +26 -31
  27. package/dist/core/stateDelivery.d.ts +3 -3
  28. package/dist/core/stateDelivery.js +10 -1
  29. package/dist/core/stateHttp.d.ts +280 -0
  30. package/dist/core/stateHttp.js +17 -0
  31. package/dist/core/stateProof.d.ts +13 -0
  32. package/dist/core/stateProof.js +34 -0
  33. package/dist/core/stateRecords.d.ts +127 -0
  34. package/dist/core/stateRecords.js +48 -0
  35. package/dist/core/taskRecord.d.ts +39 -0
  36. package/dist/core/taskRecord.js +185 -0
  37. package/dist/core/taskReport.d.ts +8 -1
  38. package/dist/core/taskReport.js +28 -14
  39. package/dist/core/taskReportEvidence.js +2 -1
  40. package/dist/core/taskReportHook.d.ts +18 -3
  41. package/dist/core/taskReportHook.js +77 -8
  42. package/dist/core/taskReportPaths.d.ts +6 -0
  43. package/dist/core/taskReportPaths.js +13 -0
  44. package/dist/core/types.d.ts +321 -4
  45. package/dist/core/types.js +47 -2
  46. package/dist/core/updatecheck.d.ts +51 -0
  47. package/dist/core/updatecheck.js +266 -0
  48. package/dist/core/version.d.ts +2 -0
  49. package/dist/core/version.js +3 -1
  50. package/dist/extractors/git.js +3 -10
  51. package/dist/integrations/gitignore.js +1 -0
  52. package/dist/integrations/health.js +27 -2
  53. package/dist/mcp/server.js +15 -5
  54. package/dist/mcp/taskReportTools.d.ts +4 -4
  55. package/dist/mcp/taskReportTools.js +32 -3
  56. package/dist/serve/app.d.ts +2 -0
  57. package/dist/serve/app.js +71 -30
  58. package/dist/serve/config.d.ts +16 -0
  59. package/dist/serve/config.js +27 -7
  60. package/dist/serve/operator.d.ts +4 -0
  61. package/dist/serve/operator.js +223 -0
  62. package/dist/serve/stateProof.d.ts +15 -0
  63. package/dist/serve/stateProof.js +105 -0
  64. package/dist/store/changeLedger.d.ts +6 -0
  65. package/dist/store/hunchStore.d.ts +9 -3
  66. package/dist/store/hunchStore.js +36 -19
  67. package/dist/store/stateAccess.d.ts +13 -0
  68. package/dist/store/stateAccess.js +85 -0
  69. package/dist/store/stateBinding.d.ts +13 -18
  70. package/dist/store/stateBinding.js +161 -52
  71. package/dist/store/stateCapture.js +10 -2
  72. package/dist/store/stateError.d.ts +12 -0
  73. package/dist/store/stateError.js +12 -0
  74. package/dist/store/statePartition.d.ts +9 -0
  75. package/dist/store/statePartition.js +30 -0
  76. package/dist/taskReports.d.ts +1 -1
  77. package/dist/taskReports.js +16 -4
  78. package/package.json +5 -1
  79. package/server.json +2 -2
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import { z } from "zod";
9
9
  import { ProvenanceSchema, isCredentialFreeText, type Provenance } from "./provenance.js";
10
- import { type ActionReceipt, type Commitment, type DerivedState, type ExternalEntity, type StateRelationship } from "./stateRecords.js";
10
+ import { type Convention, type ActionReceipt, type Commitment, type DerivedState, type ExternalEntity, type StateRelationship } from "./stateRecords.js";
11
11
  export { ProvenanceSchema, isCredentialFreeText };
12
12
  export type { Provenance };
13
13
  export declare const ComponentKind: z.ZodEnum<{
@@ -335,6 +335,11 @@ export declare const PremiseSchema: z.ZodObject<{
335
335
  }, z.core.$strip>;
336
336
  export type Premise = z.infer<typeof PremiseSchema>;
337
337
  export declare const DecisionSchema: z.ZodObject<{
338
+ visibility: z.ZodOptional<z.ZodObject<{
339
+ owner: z.ZodString;
340
+ readers: z.ZodArray<z.ZodString>;
341
+ writers: z.ZodArray<z.ZodString>;
342
+ }, z.core.$strict>>;
338
343
  id: z.ZodString;
339
344
  title: z.ZodString;
340
345
  topic: z.ZodDefault<z.ZodNullable<z.ZodString>>;
@@ -416,6 +421,11 @@ export declare const BugLineageSchema: z.ZodObject<{
416
421
  export type BugLineage = z.infer<typeof BugLineageSchema>;
417
422
  /** A bug with root cause and lineage (introduced → fixed → recurred). */
418
423
  export declare const BugSchema: z.ZodObject<{
424
+ visibility: z.ZodOptional<z.ZodObject<{
425
+ owner: z.ZodString;
426
+ readers: z.ZodArray<z.ZodString>;
427
+ writers: z.ZodArray<z.ZodString>;
428
+ }, z.core.$strict>>;
419
429
  id: z.ZodString;
420
430
  title: z.ZodString;
421
431
  symptom: z.ZodDefault<z.ZodString>;
@@ -452,6 +462,11 @@ export declare const BugSchema: z.ZodObject<{
452
462
  export type Bug = z.infer<typeof BugSchema>;
453
463
  /** An invariant the system must respect. */
454
464
  export declare const ConstraintSchema: z.ZodObject<{
465
+ visibility: z.ZodOptional<z.ZodObject<{
466
+ owner: z.ZodString;
467
+ readers: z.ZodArray<z.ZodString>;
468
+ writers: z.ZodArray<z.ZodString>;
469
+ }, z.core.$strict>>;
455
470
  id: z.ZodString;
456
471
  type: z.ZodDefault<z.ZodEnum<{
457
472
  security: "security";
@@ -526,6 +541,11 @@ export type Runbook = z.infer<typeof RunbookSchema>;
526
541
  * never enters any block path. Lifecycle is `triage`, not valid-time: a finding is
527
542
  * resolved/stale-marked, never superseded. */
528
543
  export declare const FindingSchema: z.ZodObject<{
544
+ visibility: z.ZodOptional<z.ZodObject<{
545
+ owner: z.ZodString;
546
+ readers: z.ZodArray<z.ZodString>;
547
+ writers: z.ZodArray<z.ZodString>;
548
+ }, z.core.$strict>>;
529
549
  id: z.ZodString;
530
550
  title: z.ZodString;
531
551
  observation: z.ZodDefault<z.ZodString>;
@@ -538,8 +558,8 @@ export declare const FindingSchema: z.ZodObject<{
538
558
  critical: "critical";
539
559
  }>>;
540
560
  triage: z.ZodDefault<z.ZodEnum<{
541
- open: "open";
542
561
  stale: "stale";
562
+ open: "open";
543
563
  "accepted-risk": "accepted-risk";
544
564
  scheduled: "scheduled";
545
565
  resolved: "resolved";
@@ -558,6 +578,96 @@ export declare const FindingSchema: z.ZodObject<{
558
578
  }, z.core.$strip>;
559
579
  }, z.core.$strip>;
560
580
  export type Finding = z.infer<typeof FindingSchema>;
581
+ /** A finished agent task as durable graph memory: what Hunch delivered, what the
582
+ * agent says it applied, what it saved and checked, and which files it touched.
583
+ * Written automatically when a task finishes with at least one observation; the
584
+ * raw observation ledger (.hunch-cache/served.db) stays machine-local. Titles are
585
+ * the only prose; no prompt text, transcript, or private context payload is kept. */
586
+ export declare const TaskRecordSchema: z.ZodObject<{
587
+ visibility: z.ZodOptional<z.ZodObject<{
588
+ owner: z.ZodString;
589
+ readers: z.ZodArray<z.ZodString>;
590
+ writers: z.ZodArray<z.ZodString>;
591
+ }, z.core.$strict>>;
592
+ id: z.ZodString;
593
+ title: z.ZodString;
594
+ state: z.ZodEnum<{
595
+ completed: "completed";
596
+ interrupted: "interrupted";
597
+ }>;
598
+ started_at: z.ZodString;
599
+ finished_at: z.ZodString;
600
+ coverage: z.ZodEnum<{
601
+ "no-delivery-observed": "no-delivery-observed";
602
+ "no-relevant-memory": "no-relevant-memory";
603
+ delivered: "delivered";
604
+ }>;
605
+ lessons: z.ZodDefault<z.ZodArray<z.ZodObject<{
606
+ kind: z.ZodString;
607
+ record_id: z.ZodString;
608
+ content_hash: z.ZodString;
609
+ title: z.ZodString;
610
+ }, z.core.$strip>>>;
611
+ applied: z.ZodDefault<z.ZodArray<z.ZodObject<{
612
+ record_id: z.ZodString;
613
+ content_hash: z.ZodString;
614
+ action: z.ZodString;
615
+ supported_by: z.ZodDefault<z.ZodNullable<z.ZodString>>;
616
+ }, z.core.$strip>>>;
617
+ saved: z.ZodDefault<z.ZodArray<z.ZodObject<{
618
+ kind: z.ZodString;
619
+ record_id: z.ZodString;
620
+ content_hash: z.ZodString;
621
+ home: z.ZodEnum<{
622
+ public: "public";
623
+ private: "private";
624
+ }>;
625
+ operation: z.ZodEnum<{
626
+ updated: "updated";
627
+ created: "created";
628
+ }>;
629
+ durability: z.ZodEnum<{
630
+ local: "local";
631
+ committed: "committed";
632
+ pushed: "pushed";
633
+ }>;
634
+ }, z.core.$strip>>>;
635
+ checks: z.ZodDefault<z.ZodArray<z.ZodObject<{
636
+ label: z.ZodString;
637
+ state: z.ZodEnum<{
638
+ passed: "passed";
639
+ failed: "failed";
640
+ cancelled: "cancelled";
641
+ "timed out": "timed out";
642
+ }>;
643
+ exit_code: z.ZodNullable<z.ZodNumber>;
644
+ }, z.core.$strip>>>;
645
+ conformance: z.ZodDefault<z.ZodArray<z.ZodObject<{
646
+ kind: z.ZodEnum<{
647
+ decisions: "decisions";
648
+ constraints: "constraints";
649
+ }>;
650
+ record_id: z.ZodString;
651
+ content_hash: z.ZodString;
652
+ outcome: z.ZodEnum<{
653
+ satisfied: "satisfied";
654
+ violated: "violated";
655
+ "not-exercised": "not-exercised";
656
+ unavailable: "unavailable";
657
+ }>;
658
+ }, z.core.$strip>>>;
659
+ refusals: z.ZodDefault<z.ZodNumber>;
660
+ files: z.ZodDefault<z.ZodArray<z.ZodString>>;
661
+ source_snapshot: z.ZodDefault<z.ZodNullable<z.ZodString>>;
662
+ report_hash: z.ZodString;
663
+ provenance: z.ZodObject<{
664
+ source: z.ZodString;
665
+ confidence: z.ZodNumber;
666
+ evidence: z.ZodDefault<z.ZodArray<z.ZodString>>;
667
+ last_verified: z.ZodOptional<z.ZodString>;
668
+ }, z.core.$strip>;
669
+ }, z.core.$strip>;
670
+ export type TaskRecord = z.infer<typeof TaskRecordSchema>;
561
671
  export declare const LANDSCAPE_DRIFT_CANDIDATE_SCHEMA_VERSION: "hunch.landscape-drift-candidate/1";
562
672
  /**
563
673
  * An external observer's content-addressed mismatch claim. It is intake evidence
@@ -590,7 +700,7 @@ export declare function assertLandscapeDriftCandidate(value: unknown): asserts v
590
700
  /** Convert one valid external observation into advisory Hunch memory, never graph authority. */
591
701
  export declare function landscapeDriftCandidateFinding(value: unknown): Finding;
592
702
  /** The entity collections, keyed by their on-disk directory name. */
593
- export declare const ENTITY_KINDS: readonly ["components", "resources", "edges", "symbols", "decisions", "bugs", "constraints", "runbooks", "findings", "receipts", "commitments", "derived", "entities", "relationships"];
703
+ export declare const ENTITY_KINDS: readonly ["components", "resources", "edges", "symbols", "decisions", "bugs", "constraints", "runbooks", "findings", "receipts", "commitments", "derived", "entities", "relationships", "conventions", "tasks"];
594
704
  export type EntityKind = (typeof ENTITY_KINDS)[number];
595
705
  export declare const SCHEMAS: {
596
706
  readonly components: z.ZodObject<{
@@ -753,6 +863,11 @@ export declare const SCHEMAS: {
753
863
  last_changed: z.ZodDefault<z.ZodString>;
754
864
  }, z.core.$strip>;
755
865
  readonly decisions: z.ZodObject<{
866
+ visibility: z.ZodOptional<z.ZodObject<{
867
+ owner: z.ZodString;
868
+ readers: z.ZodArray<z.ZodString>;
869
+ writers: z.ZodArray<z.ZodString>;
870
+ }, z.core.$strict>>;
756
871
  id: z.ZodString;
757
872
  title: z.ZodString;
758
873
  topic: z.ZodDefault<z.ZodNullable<z.ZodString>>;
@@ -823,6 +938,11 @@ export declare const SCHEMAS: {
823
938
  date: z.ZodString;
824
939
  }, z.core.$strip>;
825
940
  readonly bugs: z.ZodObject<{
941
+ visibility: z.ZodOptional<z.ZodObject<{
942
+ owner: z.ZodString;
943
+ readers: z.ZodArray<z.ZodString>;
944
+ writers: z.ZodArray<z.ZodString>;
945
+ }, z.core.$strict>>;
826
946
  id: z.ZodString;
827
947
  title: z.ZodString;
828
948
  symptom: z.ZodDefault<z.ZodString>;
@@ -857,6 +977,11 @@ export declare const SCHEMAS: {
857
977
  }, z.core.$strip>;
858
978
  }, z.core.$strip>;
859
979
  readonly constraints: z.ZodObject<{
980
+ visibility: z.ZodOptional<z.ZodObject<{
981
+ owner: z.ZodString;
982
+ readers: z.ZodArray<z.ZodString>;
983
+ writers: z.ZodArray<z.ZodString>;
984
+ }, z.core.$strict>>;
860
985
  id: z.ZodString;
861
986
  type: z.ZodDefault<z.ZodEnum<{
862
987
  security: "security";
@@ -919,6 +1044,11 @@ export declare const SCHEMAS: {
919
1044
  date: z.ZodString;
920
1045
  }, z.core.$strip>;
921
1046
  readonly findings: z.ZodObject<{
1047
+ visibility: z.ZodOptional<z.ZodObject<{
1048
+ owner: z.ZodString;
1049
+ readers: z.ZodArray<z.ZodString>;
1050
+ writers: z.ZodArray<z.ZodString>;
1051
+ }, z.core.$strict>>;
922
1052
  id: z.ZodString;
923
1053
  title: z.ZodString;
924
1054
  observation: z.ZodDefault<z.ZodString>;
@@ -931,8 +1061,8 @@ export declare const SCHEMAS: {
931
1061
  critical: "critical";
932
1062
  }>>;
933
1063
  triage: z.ZodDefault<z.ZodEnum<{
934
- open: "open";
935
1064
  stale: "stale";
1065
+ open: "open";
936
1066
  "accepted-risk": "accepted-risk";
937
1067
  scheduled: "scheduled";
938
1068
  resolved: "resolved";
@@ -950,7 +1080,76 @@ export declare const SCHEMAS: {
950
1080
  last_verified: z.ZodOptional<z.ZodString>;
951
1081
  }, z.core.$strip>;
952
1082
  }, z.core.$strip>;
1083
+ readonly conventions: z.ZodObject<{
1084
+ schema: z.ZodLiteral<"nuryel.convention/1">;
1085
+ id: z.ZodString;
1086
+ scope: z.ZodObject<{
1087
+ kind: z.ZodEnum<{
1088
+ repository: "repository";
1089
+ organization: "organization";
1090
+ team: "team";
1091
+ user: "user";
1092
+ }>;
1093
+ id: z.ZodString;
1094
+ }, z.core.$strict>;
1095
+ key: z.ZodString;
1096
+ value: z.ZodString;
1097
+ status: z.ZodEnum<{
1098
+ stale: "stale";
1099
+ proposed: "proposed";
1100
+ accepted: "accepted";
1101
+ withdrawn: "withdrawn";
1102
+ }>;
1103
+ sources: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
1104
+ kind: z.ZodLiteral<"record">;
1105
+ id: z.ZodString;
1106
+ record_hash: z.ZodString;
1107
+ scope: z.ZodOptional<z.ZodObject<{
1108
+ kind: z.ZodEnum<{
1109
+ repository: "repository";
1110
+ organization: "organization";
1111
+ team: "team";
1112
+ user: "user";
1113
+ }>;
1114
+ id: z.ZodString;
1115
+ }, z.core.$strict>>;
1116
+ }, z.core.$strict>, z.ZodObject<{
1117
+ kind: z.ZodLiteral<"external">;
1118
+ ref: z.ZodObject<{
1119
+ system: z.ZodString;
1120
+ object_type: z.ZodString;
1121
+ object_key: z.ZodString;
1122
+ version: z.ZodOptional<z.ZodString>;
1123
+ content_hash: z.ZodOptional<z.ZodString>;
1124
+ observed_at: z.ZodString;
1125
+ locator: z.ZodOptional<z.ZodString>;
1126
+ }, z.core.$strict>;
1127
+ }, z.core.$strict>, z.ZodObject<{
1128
+ kind: z.ZodLiteral<"schema">;
1129
+ name: z.ZodString;
1130
+ fingerprint: z.ZodString;
1131
+ }, z.core.$strict>], "kind">>;
1132
+ valid_from: z.ZodString;
1133
+ valid_to: z.ZodDefault<z.ZodNullable<z.ZodString>>;
1134
+ review_by: z.ZodString;
1135
+ provenance: z.ZodObject<{
1136
+ source: z.ZodString;
1137
+ confidence: z.ZodNumber;
1138
+ evidence: z.ZodDefault<z.ZodArray<z.ZodString>>;
1139
+ last_verified: z.ZodOptional<z.ZodString>;
1140
+ }, z.core.$strip>;
1141
+ visibility: z.ZodOptional<z.ZodObject<{
1142
+ owner: z.ZodString;
1143
+ readers: z.ZodArray<z.ZodString>;
1144
+ writers: z.ZodArray<z.ZodString>;
1145
+ }, z.core.$strict>>;
1146
+ }, z.core.$strict>;
953
1147
  readonly receipts: z.ZodObject<{
1148
+ visibility: z.ZodOptional<z.ZodObject<{
1149
+ owner: z.ZodString;
1150
+ readers: z.ZodArray<z.ZodString>;
1151
+ writers: z.ZodArray<z.ZodString>;
1152
+ }, z.core.$strict>>;
954
1153
  schema: z.ZodLiteral<"nuryel.receipt/1">;
955
1154
  id: z.ZodString;
956
1155
  scope: z.ZodObject<{
@@ -1023,6 +1222,11 @@ export declare const SCHEMAS: {
1023
1222
  }, z.core.$strip>;
1024
1223
  }, z.core.$strict>;
1025
1224
  readonly commitments: z.ZodObject<{
1225
+ visibility: z.ZodOptional<z.ZodObject<{
1226
+ owner: z.ZodString;
1227
+ readers: z.ZodArray<z.ZodString>;
1228
+ writers: z.ZodArray<z.ZodString>;
1229
+ }, z.core.$strict>>;
1026
1230
  schema: z.ZodLiteral<"nuryel.commitment/1">;
1027
1231
  id: z.ZodString;
1028
1232
  scope: z.ZodObject<{
@@ -1065,6 +1269,11 @@ export declare const SCHEMAS: {
1065
1269
  }, z.core.$strip>;
1066
1270
  }, z.core.$strict>;
1067
1271
  readonly derived: z.ZodObject<{
1272
+ visibility: z.ZodOptional<z.ZodObject<{
1273
+ owner: z.ZodString;
1274
+ readers: z.ZodArray<z.ZodString>;
1275
+ writers: z.ZodArray<z.ZodString>;
1276
+ }, z.core.$strict>>;
1068
1277
  schema: z.ZodLiteral<"nuryel.derived/1">;
1069
1278
  id: z.ZodString;
1070
1279
  scope: z.ZodObject<{
@@ -1108,6 +1317,18 @@ export declare const SCHEMAS: {
1108
1317
  name: z.ZodString;
1109
1318
  fingerprint: z.ZodString;
1110
1319
  }, z.core.$strict>], "kind">>;
1320
+ field_provenance: z.ZodOptional<z.ZodArray<z.ZodObject<{
1321
+ selector: z.ZodDiscriminatedUnion<[z.ZodObject<{
1322
+ kind: z.ZodLiteral<"json_pointer">;
1323
+ path: z.ZodString;
1324
+ }, z.core.$strict>, z.ZodObject<{
1325
+ kind: z.ZodLiteral<"text">;
1326
+ start: z.ZodNumber;
1327
+ end: z.ZodNumber;
1328
+ }, z.core.$strict>], "kind">;
1329
+ value_hash: z.ZodString;
1330
+ dependency_hashes: z.ZodArray<z.ZodString>;
1331
+ }, z.core.$strict>>>;
1111
1332
  transform_version: z.ZodString;
1112
1333
  computed_at: z.ZodString;
1113
1334
  valid_to: z.ZodDefault<z.ZodNullable<z.ZodString>>;
@@ -1142,6 +1363,11 @@ export declare const SCHEMAS: {
1142
1363
  }, z.core.$strip>;
1143
1364
  }, z.core.$strict>;
1144
1365
  readonly entities: z.ZodObject<{
1366
+ visibility: z.ZodOptional<z.ZodObject<{
1367
+ owner: z.ZodString;
1368
+ readers: z.ZodArray<z.ZodString>;
1369
+ writers: z.ZodArray<z.ZodString>;
1370
+ }, z.core.$strict>>;
1145
1371
  schema: z.ZodLiteral<"nuryel.entity/1">;
1146
1372
  id: z.ZodString;
1147
1373
  kind: z.ZodString;
@@ -1181,6 +1407,11 @@ export declare const SCHEMAS: {
1181
1407
  updated_at: z.ZodString;
1182
1408
  }, z.core.$strict>;
1183
1409
  readonly relationships: z.ZodObject<{
1410
+ visibility: z.ZodOptional<z.ZodObject<{
1411
+ owner: z.ZodString;
1412
+ readers: z.ZodArray<z.ZodString>;
1413
+ writers: z.ZodArray<z.ZodString>;
1414
+ }, z.core.$strict>>;
1184
1415
  schema: z.ZodLiteral<"nuryel.relationship/1">;
1185
1416
  id: z.ZodString;
1186
1417
  from: z.ZodString;
@@ -1217,6 +1448,90 @@ export declare const SCHEMAS: {
1217
1448
  last_verified: z.ZodOptional<z.ZodString>;
1218
1449
  }, z.core.$strip>;
1219
1450
  }, z.core.$strict>;
1451
+ readonly tasks: z.ZodObject<{
1452
+ visibility: z.ZodOptional<z.ZodObject<{
1453
+ owner: z.ZodString;
1454
+ readers: z.ZodArray<z.ZodString>;
1455
+ writers: z.ZodArray<z.ZodString>;
1456
+ }, z.core.$strict>>;
1457
+ id: z.ZodString;
1458
+ title: z.ZodString;
1459
+ state: z.ZodEnum<{
1460
+ completed: "completed";
1461
+ interrupted: "interrupted";
1462
+ }>;
1463
+ started_at: z.ZodString;
1464
+ finished_at: z.ZodString;
1465
+ coverage: z.ZodEnum<{
1466
+ "no-delivery-observed": "no-delivery-observed";
1467
+ "no-relevant-memory": "no-relevant-memory";
1468
+ delivered: "delivered";
1469
+ }>;
1470
+ lessons: z.ZodDefault<z.ZodArray<z.ZodObject<{
1471
+ kind: z.ZodString;
1472
+ record_id: z.ZodString;
1473
+ content_hash: z.ZodString;
1474
+ title: z.ZodString;
1475
+ }, z.core.$strip>>>;
1476
+ applied: z.ZodDefault<z.ZodArray<z.ZodObject<{
1477
+ record_id: z.ZodString;
1478
+ content_hash: z.ZodString;
1479
+ action: z.ZodString;
1480
+ supported_by: z.ZodDefault<z.ZodNullable<z.ZodString>>;
1481
+ }, z.core.$strip>>>;
1482
+ saved: z.ZodDefault<z.ZodArray<z.ZodObject<{
1483
+ kind: z.ZodString;
1484
+ record_id: z.ZodString;
1485
+ content_hash: z.ZodString;
1486
+ home: z.ZodEnum<{
1487
+ public: "public";
1488
+ private: "private";
1489
+ }>;
1490
+ operation: z.ZodEnum<{
1491
+ updated: "updated";
1492
+ created: "created";
1493
+ }>;
1494
+ durability: z.ZodEnum<{
1495
+ local: "local";
1496
+ committed: "committed";
1497
+ pushed: "pushed";
1498
+ }>;
1499
+ }, z.core.$strip>>>;
1500
+ checks: z.ZodDefault<z.ZodArray<z.ZodObject<{
1501
+ label: z.ZodString;
1502
+ state: z.ZodEnum<{
1503
+ passed: "passed";
1504
+ failed: "failed";
1505
+ cancelled: "cancelled";
1506
+ "timed out": "timed out";
1507
+ }>;
1508
+ exit_code: z.ZodNullable<z.ZodNumber>;
1509
+ }, z.core.$strip>>>;
1510
+ conformance: z.ZodDefault<z.ZodArray<z.ZodObject<{
1511
+ kind: z.ZodEnum<{
1512
+ decisions: "decisions";
1513
+ constraints: "constraints";
1514
+ }>;
1515
+ record_id: z.ZodString;
1516
+ content_hash: z.ZodString;
1517
+ outcome: z.ZodEnum<{
1518
+ satisfied: "satisfied";
1519
+ violated: "violated";
1520
+ "not-exercised": "not-exercised";
1521
+ unavailable: "unavailable";
1522
+ }>;
1523
+ }, z.core.$strip>>>;
1524
+ refusals: z.ZodDefault<z.ZodNumber>;
1525
+ files: z.ZodDefault<z.ZodArray<z.ZodString>>;
1526
+ source_snapshot: z.ZodDefault<z.ZodNullable<z.ZodString>>;
1527
+ report_hash: z.ZodString;
1528
+ provenance: z.ZodObject<{
1529
+ source: z.ZodString;
1530
+ confidence: z.ZodNumber;
1531
+ evidence: z.ZodDefault<z.ZodArray<z.ZodString>>;
1532
+ last_verified: z.ZodOptional<z.ZodString>;
1533
+ }, z.core.$strip>;
1534
+ }, z.core.$strip>;
1220
1535
  };
1221
1536
  export type EntityFor = {
1222
1537
  components: Component;
@@ -1228,11 +1543,13 @@ export type EntityFor = {
1228
1543
  constraints: Constraint;
1229
1544
  runbooks: Runbook;
1230
1545
  findings: Finding;
1546
+ conventions: Convention;
1231
1547
  receipts: ActionReceipt;
1232
1548
  commitments: Commitment;
1233
1549
  derived: DerivedState;
1234
1550
  entities: ExternalEntity;
1235
1551
  relationships: StateRelationship;
1552
+ tasks: TaskRecord;
1236
1553
  };
1237
1554
  /** Default provenance helper for deterministic (extracted) records. */
1238
1555
  export declare function extracted(confidence: number, evidence?: string[]): Provenance;
@@ -1,3 +1,4 @@
1
+ import { RecordVisibilitySchema } from "./recordVisibility.js";
1
2
  /**
2
3
  * Core entity schema for the Project Hunch (DESIGN.md §3).
3
4
  *
@@ -9,7 +10,7 @@ import { z } from "zod";
9
10
  import { createHash } from "node:crypto";
10
11
  import { findingId, resourceId, resourceRelationshipId } from "./ids.js";
11
12
  import { ProvenanceSchema, SENSITIVE_METADATA_KEY, isCredentialFreeText } from "./provenance.js";
12
- import { ActionReceiptSchema, CommitmentSchema, DerivedStateSchema, ExternalEntitySchema, StateRelationshipSchema, } from "./stateRecords.js";
13
+ import { ConventionSchema, ActionReceiptSchema, CommitmentSchema, DerivedStateSchema, ExternalEntitySchema, StateRelationshipSchema, } from "./stateRecords.js";
13
14
  // Provenance and the credential-free text check live in the leaf module ./provenance.js so
14
15
  // record schemas registered below can import them without a cycle; re-exported unchanged.
15
16
  export { ProvenanceSchema, isCredentialFreeText };
@@ -323,6 +324,7 @@ export const PremiseSchema = z.object({
323
324
  path: ["under"],
324
325
  });
325
326
  export const DecisionSchema = z.object({
327
+ visibility: RecordVisibilitySchema.optional(),
326
328
  id: z.string().describe("dec_*"),
327
329
  title: z.string(),
328
330
  // Decision-grounding anchor: the join key that relates a doc section, a decision,
@@ -372,6 +374,7 @@ export const BugLineageSchema = z.object({
372
374
  });
373
375
  /** A bug with root cause and lineage (introduced → fixed → recurred). */
374
376
  export const BugSchema = z.object({
377
+ visibility: RecordVisibilitySchema.optional(),
375
378
  id: z.string().describe("bug_*"),
376
379
  title: z.string(),
377
380
  symptom: z.string().default(""),
@@ -388,6 +391,7 @@ export const BugSchema = z.object({
388
391
  });
389
392
  /** An invariant the system must respect. */
390
393
  export const ConstraintSchema = z.object({
394
+ visibility: RecordVisibilitySchema.optional(),
391
395
  id: z.string().describe("con_*"),
392
396
  type: z.enum(["security", "performance", "correctness", "architecture", "compliance"]).default("correctness"),
393
397
  statement: z.string(),
@@ -448,6 +452,7 @@ export const RunbookSchema = z.object({
448
452
  * never enters any block path. Lifecycle is `triage`, not valid-time: a finding is
449
453
  * resolved/stale-marked, never superseded. */
450
454
  export const FindingSchema = z.object({
455
+ visibility: RecordVisibilitySchema.optional(),
451
456
  id: z.string().describe("fnd_*"),
452
457
  title: z.string(),
453
458
  observation: z.string().default("").describe("what was observed, in plain words"),
@@ -463,6 +468,44 @@ export const FindingSchema = z.object({
463
468
  resolved_commit: z.string().nullable().default(null).describe("the commit that fixed it (set when triage becomes resolved)"),
464
469
  provenance: ProvenanceSchema,
465
470
  });
471
+ /** A finished agent task as durable graph memory: what Hunch delivered, what the
472
+ * agent says it applied, what it saved and checked, and which files it touched.
473
+ * Written automatically when a task finishes with at least one observation; the
474
+ * raw observation ledger (.hunch-cache/served.db) stays machine-local. Titles are
475
+ * the only prose; no prompt text, transcript, or private context payload is kept. */
476
+ export const TaskRecordSchema = z.object({
477
+ visibility: RecordVisibilitySchema.optional(),
478
+ id: z.string().describe("htask_*"),
479
+ title: z.string(),
480
+ state: z.enum(["completed", "interrupted"]),
481
+ started_at: z.string(),
482
+ finished_at: z.string(),
483
+ coverage: z.enum(["no-delivery-observed", "no-relevant-memory", "delivered"]),
484
+ lessons: z.array(z.object({
485
+ kind: z.string(), record_id: z.string(), content_hash: z.string(), title: z.string(),
486
+ })).default([]).describe("exact record revisions Hunch delivered to the agent"),
487
+ applied: z.array(z.object({
488
+ record_id: z.string(), content_hash: z.string(), action: z.string(),
489
+ supported_by: z.string().nullable().default(null),
490
+ })).default([]).describe("agent-reported applications; supported_by names Hunch's own rule evaluation when one held"),
491
+ saved: z.array(z.object({
492
+ kind: z.string(), record_id: z.string(), content_hash: z.string(),
493
+ home: z.enum(["public", "private"]), operation: z.enum(["created", "updated"]),
494
+ durability: z.enum(["local", "committed", "pushed"]),
495
+ })).default([]).describe("memory the task wrote, with its actual home and proven durability"),
496
+ checks: z.array(z.object({
497
+ label: z.string(), state: z.enum(["passed", "failed", "timed out", "cancelled"]), exit_code: z.number().int().nullable(),
498
+ })).default([]).describe("independently observed command results (hunch task verify)"),
499
+ conformance: z.array(z.object({
500
+ kind: z.enum(["constraints", "decisions"]), record_id: z.string(), content_hash: z.string(),
501
+ outcome: z.enum(["satisfied", "violated", "not-exercised", "unavailable"]),
502
+ })).default([]).describe("Hunch's deterministic evaluation of each delivered rule against the changed files"),
503
+ refusals: z.number().int().nonnegative().default(0).describe("edits the native gate denied during the task"),
504
+ files: z.array(z.string()).default([]).describe("files the task touched: delivery targets, rule-checked changes, denied edits"),
505
+ source_snapshot: z.string().nullable().default(null).describe("bounded source snapshot hash at the last check, when one ran"),
506
+ report_hash: z.string().describe("content hash of the full local report this record summarizes"),
507
+ provenance: ProvenanceSchema,
508
+ });
466
509
  export const LANDSCAPE_DRIFT_CANDIDATE_SCHEMA_VERSION = "hunch.landscape-drift-candidate/1";
467
510
  const LANDSCAPE_DRIFT_HASH = /^sha256:[a-f0-9]{64}$/;
468
511
  const LANDSCAPE_DRIFT_RECEIPT_ID = /^[a-z][a-z0-9_:-]{2,127}$/;
@@ -594,7 +637,7 @@ export function landscapeDriftCandidateFinding(value) {
594
637
  // loads exactly as before, and an older build ignores directories it does not know.
595
638
  export const ENTITY_KINDS = [
596
639
  "components", "resources", "edges", "symbols", "decisions", "bugs", "constraints", "runbooks", "findings",
597
- "receipts", "commitments", "derived", "entities", "relationships",
640
+ "receipts", "commitments", "derived", "entities", "relationships", "conventions", "tasks",
598
641
  ];
599
642
  export const SCHEMAS = {
600
643
  components: ComponentSchema,
@@ -606,11 +649,13 @@ export const SCHEMAS = {
606
649
  constraints: ConstraintSchema,
607
650
  runbooks: RunbookSchema,
608
651
  findings: FindingSchema,
652
+ conventions: ConventionSchema,
609
653
  receipts: ActionReceiptSchema,
610
654
  commitments: CommitmentSchema,
611
655
  derived: DerivedStateSchema,
612
656
  entities: ExternalEntitySchema,
613
657
  relationships: StateRelationshipSchema,
658
+ tasks: TaskRecordSchema,
614
659
  };
615
660
  /** Default provenance helper for deterministic (extracted) records. */
616
661
  export function extracted(confidence, evidence = []) {
@@ -0,0 +1,51 @@
1
+ /** Best-effort update notices for interactive CLI commands.
2
+ *
3
+ * The foreground process only reads a small cache and starts an unreferenced,
4
+ * detached worker when that cache is stale. Network I/O happens in the worker,
5
+ * so an unavailable registry cannot hold the user's command open. The first
6
+ * cold invocation populates the cache; later invocations can display it.
7
+ */
8
+ import { spawn } from "node:child_process";
9
+ export interface UpdateCheckResult {
10
+ current: string;
11
+ latest: string;
12
+ }
13
+ export interface UpdateCachePathOptions {
14
+ env?: NodeJS.ProcessEnv;
15
+ home?: string;
16
+ platform?: NodeJS.Platform;
17
+ }
18
+ /** Use each platform's normal per-user cache root. This deliberately never
19
+ * creates a `.hunch` path segment: `.hunch` is the repository marker used by
20
+ * findRoot(), so placing a cache there could redirect commands to the wrong
21
+ * project. */
22
+ export declare function defaultCacheFile(opts?: UpdateCachePathOptions): string;
23
+ /** Full SemVer precedence for the release and prerelease fields. */
24
+ export declare function isNewerVersion(candidate: string, current: string): boolean;
25
+ export interface RefreshUpdateCacheOptions {
26
+ cacheFile?: string;
27
+ fetchImpl?: typeof fetch;
28
+ now?: () => number;
29
+ }
30
+ /** Worker entry point, exported so network/cache behavior is testable without
31
+ * spawning a process or contacting the real registry. */
32
+ export declare function refreshUpdateCache(opts?: RefreshUpdateCacheOptions): Promise<boolean>;
33
+ export interface ScheduleUpdateCheckOptions {
34
+ cacheFile?: string;
35
+ currentVersion?: string;
36
+ now?: () => number;
37
+ workerFile?: string;
38
+ spawnImpl?: typeof spawn;
39
+ }
40
+ /** Read any known update immediately and schedule at most one refresh per day.
41
+ * Claiming the interval before spawning also bounds offline requests: failed
42
+ * checks are not retried on every CLI command. */
43
+ export declare function scheduleUpdateCheck(opts?: ScheduleUpdateCheckOptions): UpdateCheckResult | null;
44
+ export interface UpdateCheckGateOptions {
45
+ commandName: string;
46
+ isTTY: boolean;
47
+ installed: boolean;
48
+ env?: NodeJS.ProcessEnv;
49
+ }
50
+ export declare function shouldCheckForUpdate({ commandName, isTTY, installed, env }: UpdateCheckGateOptions): boolean;
51
+ export declare function formatUpdateNotice(result: UpdateCheckResult): string;