@nebutra/founder-cemetery 0.1.3 → 0.1.5

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @nebutra/founder-cemetery
2
2
 
3
+ ## 0.1.5
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies []:
8
+ - @nebutra/capability-kit@2.0.0
9
+ - @nebutra/errors@2.0.0
10
+ - @nebutra/event-log@2.0.0
11
+ - @nebutra/content-store@0.1.5
12
+ - @nebutra/ecosystem-safety@0.1.4
13
+ - @nebutra/generation-context@0.1.4
14
+
3
15
  ## 0.1.3
4
16
 
5
17
  ### Patch Changes
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@nebutra/founder-cemetery",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Company closing, postmortem, lesson extraction, and memorial publication surface",
5
5
  "private": false,
6
6
  "license": "MIT",
7
7
  "type": "module",
8
8
  "nebutra": {
9
+ "graph": "labs",
9
10
  "status": "wip",
10
11
  "productionReady": false,
11
12
  "surface": "ecosystem-product",
@@ -24,18 +25,22 @@
24
25
  "category": "ai",
25
26
  "summary": "Ethical close-company flow and evidence-backed memorial product surface"
26
27
  },
27
- "main": "./src/index.ts",
28
- "types": "./src/index.ts",
28
+ "main": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
29
30
  "exports": {
30
- ".": "./src/index.ts"
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "import": "./dist/index.js",
34
+ "default": "./dist/index.js"
35
+ }
31
36
  },
32
37
  "dependencies": {
33
- "@nebutra/capability-kit": "0.2.2",
34
- "@nebutra/content-store": "0.1.2",
35
- "@nebutra/ecosystem-safety": "0.1.2",
36
- "@nebutra/errors": "0.1.2",
37
- "@nebutra/event-log": "0.1.2",
38
- "@nebutra/generation-context": "0.1.2"
38
+ "@nebutra/capability-kit": "2.0.0",
39
+ "@nebutra/content-store": "0.1.5",
40
+ "@nebutra/ecosystem-safety": "0.1.4",
41
+ "@nebutra/errors": "2.0.0",
42
+ "@nebutra/event-log": "2.0.0",
43
+ "@nebutra/generation-context": "0.1.4"
39
44
  },
40
45
  "devDependencies": {
41
46
  "@types/node": "^25.9.1",
@@ -56,6 +61,12 @@
56
61
  "publishConfig": {
57
62
  "access": "public"
58
63
  },
64
+ "files": [
65
+ "dist",
66
+ "README.md",
67
+ "LICENSE",
68
+ "CHANGELOG.md"
69
+ ],
59
70
  "scripts": {
60
71
  "build": "tsup",
61
72
  "test": "vitest run",
@@ -1,57 +0,0 @@
1
- {"at":"2026-05-18T15:31:08.495Z","type":"reindex","tenantId":"tenant_a","files":0}
2
- {"at":"2026-05-18T15:31:08.513Z","type":"reindex","tenantId":"tenant_a","files":0}
3
- {"at":"2026-05-18T15:31:08.519Z","type":"write","tenantId":"tenant_a","path":"cemetery/loop.json"}
4
- {"at":"2026-05-18T15:31:08.530Z","type":"reindex","tenantId":"tenant_a","files":0}
5
- {"at":"2026-05-18T15:35:24.736Z","type":"reindex","tenantId":"tenant_a","files":0}
6
- {"at":"2026-05-18T15:35:24.766Z","type":"reindex","tenantId":"tenant_a","files":0}
7
- {"at":"2026-05-18T15:35:24.771Z","type":"write","tenantId":"tenant_a","path":"cemetery/loop.json"}
8
- {"at":"2026-05-18T15:35:24.788Z","type":"reindex","tenantId":"tenant_a","files":0}
9
- {"at":"2026-05-18T15:37:13.006Z","type":"reindex","tenantId":"tenant_a","files":0}
10
- {"at":"2026-05-18T15:37:13.025Z","type":"reindex","tenantId":"tenant_a","files":0}
11
- {"at":"2026-05-18T15:37:13.030Z","type":"write","tenantId":"tenant_a","path":"cemetery/loop.json"}
12
- {"at":"2026-05-18T15:37:13.042Z","type":"reindex","tenantId":"tenant_a","files":0}
13
- {"at":"2026-05-18T15:49:27.843Z","type":"reindex","tenantId":"tenant_a","files":0}
14
- {"at":"2026-05-18T15:49:27.912Z","type":"reindex","tenantId":"tenant_a","files":0}
15
- {"at":"2026-05-18T15:49:27.942Z","type":"write","tenantId":"tenant_a","path":"cemetery/loop.json"}
16
- {"at":"2026-05-18T15:49:27.988Z","type":"reindex","tenantId":"tenant_a","files":0}
17
- {"at":"2026-05-18T15:49:28.022Z","type":"reindex","tenantId":"tenant_a","files":0}
18
- {"at":"2026-05-18T15:49:28.028Z","type":"write","tenantId":"tenant_a","path":"cemetery/loop.json"}
19
- {"at":"2026-05-18T16:03:14.166Z","type":"reindex","tenantId":"tenant_a","files":0}
20
- {"at":"2026-05-18T16:03:14.239Z","type":"reindex","tenantId":"tenant_a","files":0}
21
- {"at":"2026-05-18T16:03:14.265Z","type":"write","tenantId":"tenant_a","path":"cemetery/loop.json"}
22
- {"at":"2026-05-18T16:03:14.331Z","type":"reindex","tenantId":"tenant_a","files":0}
23
- {"at":"2026-05-18T16:03:14.360Z","type":"reindex","tenantId":"tenant_a","files":0}
24
- {"at":"2026-05-18T16:05:03.625Z","type":"reindex","tenantId":"tenant_a","files":0}
25
- {"at":"2026-05-18T16:05:03.642Z","type":"reindex","tenantId":"tenant_a","files":0}
26
- {"at":"2026-05-18T16:05:03.647Z","type":"write","tenantId":"tenant_a","path":"cemetery/loop.json"}
27
- {"at":"2026-05-18T16:05:03.657Z","type":"reindex","tenantId":"tenant_a","files":0}
28
- {"at":"2026-05-18T16:10:28.214Z","type":"reindex","tenantId":"tenant_a","files":0}
29
- {"at":"2026-05-18T16:10:28.223Z","type":"reindex","tenantId":"tenant_a","files":0}
30
- {"at":"2026-05-18T16:10:28.226Z","type":"write","tenantId":"tenant_a","path":"cemetery/loop.json"}
31
- {"at":"2026-05-18T16:10:28.236Z","type":"reindex","tenantId":"tenant_a","files":0}
32
- {"at":"2026-05-18T16:10:28.243Z","type":"reindex","tenantId":"tenant_a","files":0}
33
- {"at":"2026-05-18T16:13:16.456Z","type":"reindex","tenantId":"tenant_a","files":0}
34
- {"at":"2026-05-18T16:13:16.476Z","type":"reindex","tenantId":"tenant_a","files":0}
35
- {"at":"2026-05-18T16:13:16.482Z","type":"write","tenantId":"tenant_a","path":"cemetery/loop.json"}
36
- {"at":"2026-05-18T16:13:16.493Z","type":"reindex","tenantId":"tenant_a","files":0}
37
- {"at":"2026-05-18T16:13:16.504Z","type":"reindex","tenantId":"tenant_a","files":0}
38
- {"at":"2026-05-19T05:21:58.319Z","type":"reindex","tenantId":"tenant_a","files":0}
39
- {"at":"2026-05-19T05:21:58.328Z","type":"reindex","tenantId":"tenant_a","files":0}
40
- {"at":"2026-05-19T05:21:58.332Z","type":"write","tenantId":"tenant_a","path":"cemetery/loop.json"}
41
- {"at":"2026-05-19T05:21:58.341Z","type":"reindex","tenantId":"tenant_a","files":0}
42
- {"at":"2026-05-19T05:21:58.349Z","type":"reindex","tenantId":"tenant_a","files":0}
43
- {"at":"2026-05-19T05:25:37.516Z","type":"reindex","tenantId":"tenant_a","files":0}
44
- {"at":"2026-05-19T05:25:37.537Z","type":"reindex","tenantId":"tenant_a","files":0}
45
- {"at":"2026-05-19T05:25:37.545Z","type":"write","tenantId":"tenant_a","path":"cemetery/loop.json"}
46
- {"at":"2026-05-19T05:25:37.557Z","type":"reindex","tenantId":"tenant_a","files":0}
47
- {"at":"2026-05-19T05:25:37.570Z","type":"reindex","tenantId":"tenant_a","files":0}
48
- {"at":"2026-05-30T21:07:11.429Z","type":"reindex","tenantId":"tenant_a","files":0}
49
- {"at":"2026-05-30T21:07:11.450Z","type":"reindex","tenantId":"tenant_a","files":0}
50
- {"at":"2026-05-30T21:07:11.458Z","type":"write","tenantId":"tenant_a","path":"cemetery/loop.json"}
51
- {"at":"2026-05-30T21:07:11.480Z","type":"reindex","tenantId":"tenant_a","files":0}
52
- {"at":"2026-05-30T21:07:11.531Z","type":"reindex","tenantId":"tenant_a","files":0}
53
- {"at":"2026-07-01T01:40:42.276Z","type":"reindex","tenantId":"tenant_a","files":0}
54
- {"at":"2026-07-01T01:40:42.291Z","type":"reindex","tenantId":"tenant_a","files":0}
55
- {"at":"2026-07-01T01:40:42.299Z","type":"write","tenantId":"tenant_a","path":"cemetery/loop.json"}
56
- {"at":"2026-07-01T01:40:42.371Z","type":"reindex","tenantId":"tenant_a","files":0}
57
- {"at":"2026-07-01T01:40:42.379Z","type":"reindex","tenantId":"tenant_a","files":0}
@@ -1,13 +0,0 @@
1
- {"traceId":"founder_cemetery_publish_loop_mpbd2xrb","kind":"content_write","affected":["cemetery/loop.json"],"parent":null,"snapshot":{"cemetery/loop.json":"{\n \"slug\": \"loop\",\n \"companyId\": \"loop\",\n \"companyName\": \"Loop\",\n \"publishLevel\": \"community\",\n \"coolingOffUntil\": \"2026-05-19T15:31:08.515Z\",\n \"consentSignatures\": [\n \"alice\"\n ],\n \"causes\": [\n {\n \"category\": \"pmf\",\n \"confidence\": 0.78,\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"lessons\": [\n {\n \"title\": \"Validate demand before widening the pitch\",\n \"lessonText\": \"Loop should preserve the decision context and avoid repeating the highest-impact pmf mistake.\",\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"narrative\": \"Loop appears to have stalled around pmf.\"\n}\n"},"id":"89a27dad8d9ac65533099d98fe39c460e37b5e79cad24259139de80e72a7bfc8","tenantId":"tenant_a","at":"2026-05-18T15:31:08.521Z","summary":"content_write touched 1 path(s)","objectHashes":["d46be96b05eef6806f6f8c5dacc0cbe6b5f18c733ec24a667823c9dc27a0b617"]}
2
- {"traceId":"founder_cemetery_publish_loop_mpbd8fhf","kind":"content_write","affected":["cemetery/loop.json"],"parent":null,"snapshot":{"cemetery/loop.json":"{\n \"slug\": \"loop\",\n \"companyId\": \"loop\",\n \"companyName\": \"Loop\",\n \"publishLevel\": \"community\",\n \"coolingOffUntil\": \"2026-05-19T15:35:24.768Z\",\n \"consentSignatures\": [\n \"alice\"\n ],\n \"causes\": [\n {\n \"category\": \"pmf\",\n \"confidence\": 0.78,\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"lessons\": [\n {\n \"title\": \"Validate demand before widening the pitch\",\n \"lessonText\": \"Loop should preserve the decision context and avoid repeating the highest-impact pmf mistake.\",\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"narrative\": \"Loop appears to have stalled around pmf.\"\n}\n"},"id":"ea3b417d7e97318eec8b457c0aa38c13851e3c88bde8f7a047b75cadb7abad38","tenantId":"tenant_a","at":"2026-05-18T15:35:24.774Z","summary":"content_write touched 1 path(s)","objectHashes":["75a0ff84544ddecd333a852aa1296636bf53ff0c9916852fc1ffb197c518c7f7"]}
3
- {"traceId":"founder_cemetery_publish_loop_mpbdar0m","kind":"content_write","affected":["cemetery/loop.json"],"parent":null,"snapshot":{"cemetery/loop.json":"{\n \"slug\": \"loop\",\n \"companyId\": \"loop\",\n \"companyName\": \"Loop\",\n \"publishLevel\": \"community\",\n \"coolingOffUntil\": \"2026-05-19T15:37:13.027Z\",\n \"consentSignatures\": [\n \"alice\"\n ],\n \"causes\": [\n {\n \"category\": \"pmf\",\n \"confidence\": 0.78,\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"lessons\": [\n {\n \"title\": \"Validate demand before widening the pitch\",\n \"lessonText\": \"Loop should preserve the decision context and avoid repeating the highest-impact pmf mistake.\",\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"narrative\": \"Loop appears to have stalled around pmf.\"\n}\n"},"id":"6e632f1a15e51de187f05fcf8b8c05ec54ee39ef784de41273b5f7fbccfaa7d3","tenantId":"tenant_a","at":"2026-05-18T15:37:13.032Z","summary":"content_write touched 1 path(s)","objectHashes":["3965bcfe30b4fcad9e8082bc9ce3d836696436168c404ad7d221a63fcd1f0e00"]}
4
- {"traceId":"founder_cemetery_publish_loop_mpbdqi2x","kind":"content_write","affected":["cemetery/loop.json"],"parent":null,"snapshot":{"cemetery/loop.json":"{\n \"slug\": \"loop\",\n \"companyId\": \"loop\",\n \"companyName\": \"Loop\",\n \"publishLevel\": \"community\",\n \"coolingOffUntil\": \"2026-05-19T15:49:27.927Z\",\n \"consentSignatures\": [\n \"alice\"\n ],\n \"causes\": [\n {\n \"category\": \"pmf\",\n \"confidence\": 0.78,\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"lessons\": [\n {\n \"title\": \"Validate demand before widening the pitch\",\n \"lessonText\": \"Loop should preserve the decision context and avoid repeating the highest-impact pmf mistake.\",\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"narrative\": \"Loop appears to have stalled around pmf.\"\n}\n"},"id":"bebbbb066bd45ba8de7625f2b31a45b79301823428e58265c752492cca37cbf7","tenantId":"tenant_a","at":"2026-05-18T15:49:27.951Z","summary":"content_write touched 1 path(s)","objectHashes":["86ad0178ea23fb7b621edfb66e8062e02eaef24007e447794006f03e162e82b5"]}
5
- {"traceId":"founder_cemetery_publish_loop_mpbdqi59","kind":"content_write","affected":["cemetery/loop.json"],"parent":null,"snapshot":{"cemetery/loop.json":"{\n \"slug\": \"loop\",\n \"companyId\": \"loop\",\n \"companyName\": \"Loop\",\n \"publishLevel\": \"community\",\n \"coolingOffUntil\": \"2026-05-19T15:49:28.024Z\",\n \"consentSignatures\": [\n \"alice\"\n ],\n \"causes\": [\n {\n \"category\": \"pmf\",\n \"confidence\": 0.68,\n \"evidence\": [\n \"A customer alice@example.com churned during the final sales push\"\n ]\n }\n ],\n \"lessons\": [\n {\n \"title\": \"Validate demand before widening the pitch\",\n \"lessonText\": \"Loop should preserve the decision context and avoid repeating the highest-impact pmf mistake.\",\n \"evidence\": [\n \"A customer alice@example.com churned during the final sales push\"\n ]\n }\n ],\n \"narrative\": \"Loop appears to have stalled around pmf.\"\n}\n"},"id":"b2577646900b707c46fb04189d63d2be6936969834d709167d2c4e34cea91ad9","tenantId":"tenant_a","at":"2026-05-18T15:49:28.032Z","summary":"content_write touched 1 path(s)","objectHashes":["575bc3306447e6e5e585b8ef78c1e45788eec1d078544db769d6ceb9abdf1e96"]}
6
- {"traceId":"founder_cemetery_publish_loop_mpbe87od","kind":"content_write","affected":["cemetery/loop.json"],"parent":null,"snapshot":{"cemetery/loop.json":"{\n \"slug\": \"loop\",\n \"companyId\": \"loop\",\n \"companyName\": \"Loop\",\n \"publishLevel\": \"community\",\n \"coolingOffUntil\": \"2026-05-19T16:03:14.252Z\",\n \"consentSignatures\": [\n \"alice\"\n ],\n \"redactions\": [],\n \"causes\": [\n {\n \"category\": \"pmf\",\n \"confidence\": 0.78,\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"lessons\": [\n {\n \"title\": \"Validate demand before widening the pitch\",\n \"lessonText\": \"Loop should preserve the decision context and avoid repeating the highest-impact pmf mistake.\",\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"narrative\": \"Loop appears to have stalled around pmf.\"\n}\n"},"id":"ef4219739a4d3e7ca0921d5f4a05837470abab01e4258a8289071a69c34e58bc","tenantId":"tenant_a","at":"2026-05-18T16:03:14.279Z","summary":"content_write touched 1 path(s)","objectHashes":["d5acc54b5b0b767a5bab2a4bc122278521cadd59a5162e26a172cd937fdbfbff"]}
7
- {"traceId":"founder_cemetery_publish_loop_mpbeak2n","kind":"content_write","affected":["cemetery/loop.json"],"parent":null,"snapshot":{"cemetery/loop.json":"{\n \"slug\": \"loop\",\n \"companyId\": \"loop\",\n \"companyName\": \"Loop\",\n \"publishLevel\": \"community\",\n \"coolingOffUntil\": \"2026-05-19T16:05:03.643Z\",\n \"consentSignatures\": [\n \"alice\"\n ],\n \"causes\": [\n {\n \"category\": \"pmf\",\n \"confidence\": 0.78,\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"lessons\": [\n {\n \"title\": \"Validate demand before widening the pitch\",\n \"lessonText\": \"Loop should preserve the decision context and avoid repeating the highest-impact pmf mistake.\",\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"narrative\": \"Loop appears to have stalled around pmf.\"\n}\n"},"id":"fd99700bde8a31f4354fb671279d4954abd6a0d8b4640f2ba694798280b5ceed","tenantId":"tenant_a","at":"2026-05-18T16:05:03.650Z","summary":"content_write touched 1 path(s)","objectHashes":["bf0db0c6ad6602a9d37ae6a46177e4afc1815297a1afc38042e852044e5c054f"]}
8
- {"traceId":"founder_cemetery_publish_loop_mpbehiiq","kind":"content_write","affected":["cemetery/loop.json"],"parent":null,"snapshot":{"cemetery/loop.json":"{\n \"slug\": \"loop\",\n \"companyId\": \"loop\",\n \"companyName\": \"Loop\",\n \"publishLevel\": \"community\",\n \"coolingOffUntil\": \"2026-05-19T16:10:28.224Z\",\n \"consentSignatures\": [\n \"alice\"\n ],\n \"redactions\": [],\n \"causes\": [\n {\n \"category\": \"pmf\",\n \"confidence\": 0.78,\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"lessons\": [\n {\n \"title\": \"Validate demand before widening the pitch\",\n \"lessonText\": \"Loop should preserve the decision context and avoid repeating the highest-impact pmf mistake.\",\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"narrative\": \"Loop appears to have stalled around pmf.\"\n}\n"},"id":"fe7d676166ef3c41dab811b3ef47c2a726561a3a72537834de50696d5bce66e8","tenantId":"tenant_a","at":"2026-05-18T16:10:28.229Z","summary":"content_write touched 1 path(s)","objectHashes":["f65858d8596c42c9fa591fc133f52c4c20f8181e362871e5a7f9e33e1beebfaa"]}
9
- {"traceId":"founder_cemetery_publish_loop_mpbel4ci","kind":"content_write","affected":["cemetery/loop.json"],"parent":null,"snapshot":{"cemetery/loop.json":"{\n \"slug\": \"loop\",\n \"companyId\": \"loop\",\n \"companyName\": \"Loop\",\n \"publishLevel\": \"community\",\n \"coolingOffUntil\": \"2026-05-19T16:13:16.477Z\",\n \"consentSignatures\": [\n \"alice\"\n ],\n \"redactions\": [],\n \"causes\": [\n {\n \"category\": \"pmf\",\n \"confidence\": 0.78,\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"lessons\": [\n {\n \"title\": \"Validate demand before widening the pitch\",\n \"lessonText\": \"Loop should preserve the decision context and avoid repeating the highest-impact pmf mistake.\",\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"narrative\": \"Loop appears to have stalled around pmf.\"\n}\n"},"id":"d0c7717c719821a5aeb6477c66b9d88b8da0368dfc086040d93cdb21829a1041","tenantId":"tenant_a","at":"2026-05-18T16:13:16.485Z","summary":"content_write touched 1 path(s)","objectHashes":["daab2220ca593b98da75e83e7359f7ab61b5110ed8689e3281c37112bbb392cd"]}
10
- {"traceId":"founder_cemetery_publish_loop_mpc6re4c","kind":"content_write","affected":["cemetery/loop.json"],"parent":null,"snapshot":{"cemetery/loop.json":"{\n \"slug\": \"loop\",\n \"companyId\": \"loop\",\n \"companyName\": \"Loop\",\n \"publishLevel\": \"community\",\n \"coolingOffUntil\": \"2026-05-20T05:21:58.330Z\",\n \"consentSignatures\": [\n \"alice\"\n ],\n \"redactions\": [],\n \"causes\": [\n {\n \"category\": \"pmf\",\n \"confidence\": 0.78,\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"lessons\": [\n {\n \"title\": \"Validate demand before widening the pitch\",\n \"lessonText\": \"Loop should preserve the decision context and avoid repeating the highest-impact pmf mistake.\",\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"narrative\": \"Loop appears to have stalled around pmf.\"\n}\n"},"id":"00d5a8e339509c6bed7570e46f8cea39b6e5e445806e1cf661ec50ff8e589fbb","tenantId":"tenant_a","at":"2026-05-19T05:21:58.334Z","summary":"content_write touched 1 path(s)","objectHashes":["081dffed2bd22f65524c0561b98a39a42525b13f5e5ba232aa59813e81172d73"]}
11
- {"traceId":"founder_cemetery_publish_loop_mpc6w39m","kind":"content_write","affected":["cemetery/loop.json"],"parent":null,"snapshot":{"cemetery/loop.json":"{\n \"slug\": \"loop\",\n \"companyId\": \"loop\",\n \"companyName\": \"Loop\",\n \"publishLevel\": \"community\",\n \"coolingOffUntil\": \"2026-05-20T05:25:37.539Z\",\n \"consentSignatures\": [\n \"alice\"\n ],\n \"redactions\": [],\n \"causes\": [\n {\n \"category\": \"pmf\",\n \"confidence\": 0.78,\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"lessons\": [\n {\n \"title\": \"Validate demand before widening the pitch\",\n \"lessonText\": \"Loop should preserve the decision context and avoid repeating the highest-impact pmf mistake.\",\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"narrative\": \"Loop appears to have stalled around pmf.\"\n}\n"},"id":"e75289258886bd1004bb837fc5e572ec945a836c7bcba0bfcf734764cb2b4efc","tenantId":"tenant_a","at":"2026-05-19T05:25:37.549Z","summary":"content_write touched 1 path(s)","objectHashes":["de13776fdbfdf08fed7fec677529234d87dd6cde7a8334b0c4318f2e68188b24"]}
12
- {"at":"2026-05-30T21:07:11.461Z","traceId":"founder_cemetery_publish_loop_mpsudbky","kind":"content_write","affected":["cemetery/loop.json"],"parent":null,"snapshot":{"cemetery/loop.json":"{\n \"slug\": \"loop\",\n \"companyId\": \"loop\",\n \"companyName\": \"Loop\",\n \"publishLevel\": \"community\",\n \"coolingOffUntil\": \"2026-05-31T21:07:11.453Z\",\n \"consentSignatures\": [\n \"alice\"\n ],\n \"redactions\": [],\n \"causes\": [\n {\n \"category\": \"pmf\",\n \"confidence\": 0.78,\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"lessons\": [\n {\n \"title\": \"Validate demand before widening the pitch\",\n \"lessonText\": \"Loop should preserve the decision context and avoid repeating the highest-impact pmf mistake.\",\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"narrative\": \"Loop appears to have stalled around pmf.\"\n}\n"},"id":"11d4a1a44c7894cf787e1e861c1577ba79099f95ca15e91537cc721fd091424c","tenantId":"tenant_a","summary":"content_write touched 1 path(s)","objectHashes":["cdcfb5039be377257b2e77965e7064c003acce2ca55d5ba8c74b1e0f906c5df7"]}
13
- {"at":"2026-07-01T01:40:42.354Z","traceId":"founder_cemetery_publish_loop_mr1esgxn","kind":"content_write","affected":["cemetery/loop.json"],"parent":null,"snapshot":{"cemetery/loop.json":"{\n \"slug\": \"loop\",\n \"companyId\": \"loop\",\n \"companyName\": \"Loop\",\n \"publishLevel\": \"community\",\n \"coolingOffUntil\": \"2026-07-02T01:40:42.294Z\",\n \"consentSignatures\": [\n \"alice\"\n ],\n \"redactions\": [],\n \"causes\": [\n {\n \"category\": \"pmf\",\n \"confidence\": 0.78,\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"lessons\": [\n {\n \"title\": \"Validate demand before widening the pitch\",\n \"lessonText\": \"Loop should preserve the decision context and avoid repeating the highest-impact pmf mistake.\",\n \"evidence\": [\n \"Pivoted from devtools to sales without user interviews\",\n \"Outbound reply rate stayed below 1 percent\"\n ]\n }\n ],\n \"narrative\": \"Loop appears to have stalled around pmf.\"\n}\n"},"id":"5077a9e560f89affa28d402392eafd9cb0ca8117ed1a5b2e60ad61fc42576bd2","tenantId":"tenant_a","summary":"content_write touched 1 path(s)","objectHashes":["c9fda7b0fc1a59f64e20703ab0d0bf293ef7eaf3665d9a0391d5a90dc3d1fc54"]}
@@ -1,89 +0,0 @@
1
- {"at":"2026-05-18T15:31:08.499Z","type":"start_closing_flow","tenantId":"tenant_a","companyId":"loop","companyName":"Loop","recommendedMode":"pause","availableModes":["pause","archive","cemetery"],"requiresCoolingOff":true,"startedAt":"2026-05-18T15:31:08.499Z"}
2
- {"at":"2026-05-18T15:31:08.514Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"pmf"}
3
- {"at":"2026-05-18T15:31:08.515Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
4
- {"at":"2026-05-18T15:31:08.521Z","type":"publish_memorial","tenantId":"tenant_a","companyId":"loop","publishLevel":"community"}
5
- {"at":"2026-05-18T15:31:08.530Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"runway"}
6
- {"at":"2026-05-18T15:31:08.530Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
7
- {"at":"2026-05-18T15:35:24.738Z","type":"start_closing_flow","tenantId":"tenant_a","companyId":"loop","companyName":"Loop","recommendedMode":"pause","availableModes":["pause","archive","cemetery"],"requiresCoolingOff":true,"startedAt":"2026-05-18T15:35:24.738Z"}
8
- {"at":"2026-05-18T15:35:24.767Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"pmf"}
9
- {"at":"2026-05-18T15:35:24.767Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
10
- {"at":"2026-05-18T15:35:24.776Z","type":"publish_memorial","tenantId":"tenant_a","companyId":"loop","publishLevel":"community"}
11
- {"at":"2026-05-18T15:35:24.789Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"runway"}
12
- {"at":"2026-05-18T15:35:24.789Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
13
- {"at":"2026-05-18T15:37:13.010Z","type":"start_closing_flow","tenantId":"tenant_a","companyId":"loop","companyName":"Loop","recommendedMode":"pause","availableModes":["pause","archive","cemetery"],"requiresCoolingOff":true,"startedAt":"2026-05-18T15:37:13.009Z"}
14
- {"at":"2026-05-18T15:37:13.026Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"pmf"}
15
- {"at":"2026-05-18T15:37:13.026Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
16
- {"at":"2026-05-18T15:37:13.034Z","type":"publish_memorial","tenantId":"tenant_a","companyId":"loop","publishLevel":"community"}
17
- {"at":"2026-05-18T15:37:13.043Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"runway"}
18
- {"at":"2026-05-18T15:37:13.043Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
19
- {"at":"2026-05-18T15:49:27.862Z","type":"start_closing_flow","tenantId":"tenant_a","companyId":"loop","companyName":"Loop","recommendedMode":"pause","availableModes":["pause","archive","cemetery"],"requiresCoolingOff":true,"startedAt":"2026-05-18T15:49:27.857Z"}
20
- {"at":"2026-05-18T15:49:27.920Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"pmf"}
21
- {"at":"2026-05-18T15:49:27.926Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
22
- {"at":"2026-05-18T15:49:27.956Z","type":"publish_memorial","tenantId":"tenant_a","companyId":"loop","publishLevel":"community"}
23
- {"at":"2026-05-18T15:49:27.990Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"runway"}
24
- {"at":"2026-05-18T15:49:27.990Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
25
- {"at":"2026-05-18T15:49:28.023Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"pmf"}
26
- {"at":"2026-05-18T15:49:28.024Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
27
- {"at":"2026-05-18T15:49:28.035Z","type":"publish_memorial","tenantId":"tenant_a","companyId":"loop","publishLevel":"community"}
28
- {"at":"2026-05-18T16:03:14.182Z","type":"start_closing_flow","tenantId":"tenant_a","companyId":"loop","companyName":"Loop","recommendedMode":"pause","availableModes":["pause","archive","cemetery"],"requiresCoolingOff":true,"startedAt":"2026-05-18T16:03:14.179Z"}
29
- {"at":"2026-05-18T16:03:14.249Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"pmf"}
30
- {"at":"2026-05-18T16:03:14.250Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
31
- {"at":"2026-05-18T16:03:14.284Z","type":"publish_memorial","tenantId":"tenant_a","companyId":"loop","publishLevel":"community"}
32
- {"at":"2026-05-18T16:03:14.333Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"runway"}
33
- {"at":"2026-05-18T16:03:14.334Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
34
- {"at":"2026-05-18T16:03:14.362Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"pmf"}
35
- {"at":"2026-05-18T16:03:14.362Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
36
- {"at":"2026-05-18T16:05:03.628Z","type":"start_closing_flow","tenantId":"tenant_a","companyId":"loop","companyName":"Loop","recommendedMode":"pause","availableModes":["pause","archive","cemetery"],"requiresCoolingOff":true,"startedAt":"2026-05-18T16:05:03.628Z"}
37
- {"at":"2026-05-18T16:05:03.643Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"pmf"}
38
- {"at":"2026-05-18T16:05:03.643Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
39
- {"at":"2026-05-18T16:05:03.650Z","type":"publish_memorial","tenantId":"tenant_a","companyId":"loop","publishLevel":"community"}
40
- {"at":"2026-05-18T16:05:03.658Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"runway"}
41
- {"at":"2026-05-18T16:05:03.658Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
42
- {"at":"2026-05-18T16:10:28.216Z","type":"start_closing_flow","tenantId":"tenant_a","companyId":"loop","companyName":"Loop","recommendedMode":"pause","availableModes":["pause","archive","cemetery"],"requiresCoolingOff":true,"startedAt":"2026-05-18T16:10:28.216Z"}
43
- {"at":"2026-05-18T16:10:28.223Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"pmf"}
44
- {"at":"2026-05-18T16:10:28.223Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
45
- {"at":"2026-05-18T16:10:28.230Z","type":"publish_memorial","tenantId":"tenant_a","companyId":"loop","publishLevel":"community"}
46
- {"at":"2026-05-18T16:10:28.236Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"runway"}
47
- {"at":"2026-05-18T16:10:28.237Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
48
- {"at":"2026-05-18T16:10:28.244Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"pmf"}
49
- {"at":"2026-05-18T16:10:28.244Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
50
- {"at":"2026-05-18T16:13:16.459Z","type":"start_closing_flow","tenantId":"tenant_a","companyId":"loop","companyName":"Loop","recommendedMode":"pause","availableModes":["pause","archive","cemetery"],"requiresCoolingOff":true,"startedAt":"2026-05-18T16:13:16.459Z"}
51
- {"at":"2026-05-18T16:13:16.476Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"pmf"}
52
- {"at":"2026-05-18T16:13:16.477Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
53
- {"at":"2026-05-18T16:13:16.486Z","type":"publish_memorial","tenantId":"tenant_a","companyId":"loop","publishLevel":"community"}
54
- {"at":"2026-05-18T16:13:16.494Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"runway"}
55
- {"at":"2026-05-18T16:13:16.494Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
56
- {"at":"2026-05-18T16:13:16.504Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"pmf"}
57
- {"at":"2026-05-18T16:13:16.505Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
58
- {"at":"2026-05-19T05:21:58.321Z","type":"start_closing_flow","tenantId":"tenant_a","companyId":"loop","companyName":"Loop","recommendedMode":"pause","availableModes":["pause","archive","cemetery"],"requiresCoolingOff":true,"startedAt":"2026-05-19T05:21:58.320Z"}
59
- {"at":"2026-05-19T05:21:58.329Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"pmf"}
60
- {"at":"2026-05-19T05:21:58.329Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
61
- {"at":"2026-05-19T05:21:58.335Z","type":"publish_memorial","tenantId":"tenant_a","companyId":"loop","publishLevel":"community"}
62
- {"at":"2026-05-19T05:21:58.342Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"runway"}
63
- {"at":"2026-05-19T05:21:58.342Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
64
- {"at":"2026-05-19T05:21:58.350Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"pmf"}
65
- {"at":"2026-05-19T05:21:58.350Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
66
- {"at":"2026-05-19T05:25:37.520Z","type":"start_closing_flow","tenantId":"tenant_a","companyId":"loop","companyName":"Loop","recommendedMode":"pause","availableModes":["pause","archive","cemetery"],"requiresCoolingOff":true,"startedAt":"2026-05-19T05:25:37.519Z"}
67
- {"at":"2026-05-19T05:25:37.538Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"pmf"}
68
- {"at":"2026-05-19T05:25:37.539Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
69
- {"at":"2026-05-19T05:25:37.551Z","type":"publish_memorial","tenantId":"tenant_a","companyId":"loop","publishLevel":"community"}
70
- {"at":"2026-05-19T05:25:37.559Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"runway"}
71
- {"at":"2026-05-19T05:25:37.559Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
72
- {"at":"2026-05-19T05:25:37.571Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"pmf"}
73
- {"at":"2026-05-19T05:25:37.572Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
74
- {"at":"2026-05-30T21:07:11.433Z","type":"start_closing_flow","tenantId":"tenant_a","companyId":"loop","companyName":"Loop","recommendedMode":"pause","availableModes":["pause","archive","cemetery"],"requiresCoolingOff":true,"startedAt":"2026-05-30T21:07:11.433Z"}
75
- {"at":"2026-05-30T21:07:11.452Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"pmf"}
76
- {"at":"2026-05-30T21:07:11.452Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
77
- {"at":"2026-05-30T21:07:11.470Z","type":"publish_memorial","tenantId":"tenant_a","companyId":"loop","publishLevel":"community"}
78
- {"at":"2026-05-30T21:07:11.481Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"runway"}
79
- {"at":"2026-05-30T21:07:11.482Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
80
- {"at":"2026-05-30T21:07:11.533Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"pmf"}
81
- {"at":"2026-05-30T21:07:11.536Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
82
- {"at":"2026-07-01T01:40:42.282Z","type":"start_closing_flow","tenantId":"tenant_a","companyId":"loop","companyName":"Loop","recommendedMode":"pause","availableModes":["pause","archive","cemetery"],"requiresCoolingOff":true,"startedAt":"2026-07-01T01:40:42.279Z"}
83
- {"at":"2026-07-01T01:40:42.292Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"pmf"}
84
- {"at":"2026-07-01T01:40:42.293Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
85
- {"at":"2026-07-01T01:40:42.357Z","type":"publish_memorial","tenantId":"tenant_a","companyId":"loop","publishLevel":"community"}
86
- {"at":"2026-07-01T01:40:42.372Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"runway"}
87
- {"at":"2026-07-01T01:40:42.372Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
88
- {"at":"2026-07-01T01:40:42.380Z","type":"analyze_death","tenantId":"tenant_a","companyId":"loop","category":"pmf"}
89
- {"at":"2026-07-01T01:40:42.380Z","type":"extract_lessons","tenantId":"tenant_a","companyId":"loop","lessons":1}
@@ -1,22 +0,0 @@
1
-
2
- > @nebutra/founder-cemetery@0.1.3 build /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/founder-cemetery
3
- > tsup
4
-
5
- CLI Building entry: src/cli.ts, src/index.ts
6
- CLI Using tsconfig: tsconfig.json
7
- CLI tsup v8.5.1
8
- CLI Using tsup config: /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/founder-cemetery/tsup.config.ts
9
- CLI Target: es2022
10
- CLI Cleaning output folder
11
- ESM Build start
12
- ESM dist/index.js 176.00 B
13
- ESM dist/chunk-NUTC3QQ4.js 7.11 KB
14
- ESM dist/cli.js 1.16 KB
15
- ESM dist/cli.js.map 2.06 KB
16
- ESM dist/chunk-NUTC3QQ4.js.map 15.06 KB
17
- ESM dist/index.js.map 71.00 B
18
- ESM ⚡️ Build success in 15ms
19
- DTS Build start
20
- DTS ⚡️ Build success in 2854ms
21
- DTS dist/cli.d.ts 13.00 B
22
- DTS dist/index.d.ts 3.22 KB
@@ -1,16 +0,0 @@
1
-
2
- > @nebutra/founder-cemetery@0.1.2 test /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/founder-cemetery
3
- > vitest run
4
-
5
-
6
- RUN v4.1.4 /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/founder-cemetery
7
-
8
- (node:57241) ExperimentalWarning: SQLite is an experimental feature and might change at any time
9
- (Use `node --trace-warnings ...` to show where the warning was created)
10
- ✓ src/index.test.ts (4 tests) 121ms
11
-
12
- Test Files 1 passed (1)
13
- Tests 4 passed (4)
14
- Start at 09:40:40
15
- Duration 2.01s (transform 448ms, setup 0ms, import 491ms, tests 121ms, environment 0ms)
16
-
@@ -1,4 +0,0 @@
1
-
2
- > @nebutra/founder-cemetery@0.1.3 typecheck /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/founder-cemetery
3
- > tsc --noEmit
4
-
@@ -1,11 +0,0 @@
1
- import { FounderCemetery } from "../src/index";
2
-
3
- const cemetery = await FounderCemetery.open(".nebutra/founder-cemetery-example", {
4
- tenantId: "local",
5
- });
6
-
7
- try {
8
- process.stdout.write(`${JSON.stringify(await cemetery.doctor(), null, 2)}\n`);
9
- } finally {
10
- await cemetery.close();
11
- }
@@ -1,19 +0,0 @@
1
- import { FounderCemetery } from "../src/index";
2
-
3
- const cemetery = await FounderCemetery.open(".nebutra/founder-cemetery-memorial-example", {
4
- tenantId: "local",
5
- });
6
-
7
- try {
8
- const analysis = await cemetery.analyzeDeath({
9
- companyId: "loop",
10
- companyName: "Loop",
11
- timelineSummaries: ["Pivoted twice before validating customer demand", "Outbound stayed flat"],
12
- });
13
- const lessons = await cemetery.extractLessons(analysis);
14
- process.stdout.write(
15
- `${JSON.stringify(await cemetery.publishMemorial({ analysis, lessons, publishLevel: "community", consentSignatures: ["alice"] }), null, 2)}\n`,
16
- );
17
- } finally {
18
- await cemetery.close();
19
- }
@@ -1,16 +0,0 @@
1
- import { FounderCemetery } from "../src/index";
2
-
3
- const cemetery = await FounderCemetery.open(".nebutra/founder-cemetery-example", {
4
- tenantId: "local",
5
- });
6
-
7
- try {
8
- const flow = await cemetery.startClosingFlow({
9
- companyId: "loop",
10
- companyName: "Loop",
11
- founderIds: ["alice"],
12
- });
13
- process.stdout.write(`${JSON.stringify(flow, null, 2)}\n`);
14
- } finally {
15
- await cemetery.close();
16
- }
@@ -1,23 +0,0 @@
1
- ---
2
- name: close_company
3
- kind: play
4
- version: 1.0.0
5
- description: Guide a founder through pause, archive, or evidence-backed memorial publishing
6
- required_skills:
7
- - content_store.write
8
- - event_log.commit
9
- sub_agents:
10
- - role: postmortem_curator
11
- allowed_skills: [content_store.write]
12
- depends_on_plays: []
13
- ---
14
-
15
- ## What this play does
16
-
17
- Starts with a reversible pause recommendation, then helps the founder decide whether to archive or publish a memorial.
18
-
19
- ## Boundaries
20
-
21
- - There is no one-click delete.
22
- - Public memorials need consent and a cooling-off period.
23
- - Lessons must link back to evidence from the company timeline.
package/src/cli.ts DELETED
@@ -1,33 +0,0 @@
1
- import { FounderCemetery, readFounderCemeteryDebug } from "./index";
2
-
3
- const command = process.argv[2] ?? "doctor";
4
- const root = process.env.FOUNDER_CEMETERY_ROOT ?? ".nebutra/founder-cemetery";
5
- const tenantId = process.env.NEBUTRA_TENANT_ID ?? "local";
6
-
7
- if (command === "doctor") {
8
- const cemetery = await FounderCemetery.open(root, { tenantId });
9
- try {
10
- process.stdout.write(`${JSON.stringify(await cemetery.doctor(), null, 2)}\n`);
11
- } finally {
12
- await cemetery.close();
13
- }
14
- } else if (command === "quickstart") {
15
- const cemetery = await FounderCemetery.open(root, { tenantId });
16
- try {
17
- const flow = await cemetery.startClosingFlow({
18
- companyId: "loop",
19
- companyName: "Loop",
20
- founderIds: ["alice"],
21
- });
22
- process.stdout.write(`${JSON.stringify(flow, null, 2)}\n`);
23
- } finally {
24
- await cemetery.close();
25
- }
26
- } else if (command === "debug") {
27
- process.stdout.write(
28
- `${JSON.stringify({ capability: "founder-cemetery", entries: await readFounderCemeteryDebug() }, null, 2)}\n`,
29
- );
30
- } else {
31
- process.stderr.write(`Unknown founder-cemetery command: ${command}\n`);
32
- process.exitCode = 1;
33
- }
package/src/index.test.ts DELETED
@@ -1,104 +0,0 @@
1
- import { mkdtemp, rm } from "node:fs/promises";
2
- import { tmpdir } from "node:os";
3
- import { join } from "node:path";
4
- import { afterEach, describe, expect, it } from "vitest";
5
- import { FounderCemetery, readFounderCemeteryDebug } from "./index";
6
-
7
- let root: string | undefined;
8
- let cemetery: FounderCemetery | undefined;
9
-
10
- afterEach(async () => {
11
- if (cemetery) await cemetery.close();
12
- if (root) await rm(root, { recursive: true, force: true });
13
- root = undefined;
14
- cemetery = undefined;
15
- });
16
-
17
- async function open(): Promise<FounderCemetery> {
18
- root = await mkdtemp(join(tmpdir(), "founder-cemetery-"));
19
- cemetery = await FounderCemetery.open(root, { tenantId: "tenant_a" });
20
- return cemetery;
21
- }
22
-
23
- describe("founder-cemetery", () => {
24
- it("starts with pause as the safe default instead of one-click deletion", async () => {
25
- const runtime = await open();
26
-
27
- const flow = await runtime.startClosingFlow({
28
- companyId: "loop",
29
- companyName: "Loop",
30
- founderIds: ["alice"],
31
- });
32
-
33
- expect(flow.recommendedMode).toBe("pause");
34
- expect(flow.availableModes).toEqual(["pause", "archive", "cemetery"]);
35
- expect(flow.requiresCoolingOff).toBe(true);
36
- });
37
-
38
- it("extracts evidence-backed lessons and publishes only with consent", async () => {
39
- const runtime = await open();
40
- const analysis = await runtime.analyzeDeath({
41
- companyId: "loop",
42
- companyName: "Loop",
43
- timelineSummaries: [
44
- "Pivoted from devtools to sales without user interviews",
45
- "Outbound reply rate stayed below 1 percent",
46
- ],
47
- });
48
- const lessons = await runtime.extractLessons(analysis);
49
- const memorial = await runtime.publishMemorial({
50
- analysis,
51
- lessons,
52
- publishLevel: "community",
53
- consentSignatures: ["alice"],
54
- });
55
-
56
- expect(analysis.causes[0]?.category).toBe("pmf");
57
- expect(lessons[0]?.evidence).toHaveLength(2);
58
- expect(memorial.path).toBe(`cemetery/${memorial.slug}.json`);
59
- expect(memorial.coolingOffUntil).toEqual(expect.any(String));
60
- });
61
-
62
- it("refuses public memorials without explicit consent", async () => {
63
- const runtime = await open();
64
- const analysis = await runtime.analyzeDeath({
65
- companyId: "loop",
66
- companyName: "Loop",
67
- timelineSummaries: ["Ran out of runway after failed raise"],
68
- });
69
-
70
- await expect(
71
- runtime.publishMemorial({
72
- analysis,
73
- lessons: await runtime.extractLessons(analysis),
74
- publishLevel: "public",
75
- consentSignatures: [],
76
- }),
77
- ).rejects.toMatchObject({
78
- capability: "founder-cemetery",
79
- suggestion: expect.stringContaining("consent"),
80
- });
81
- await expect(readFounderCemeteryDebug(root)).resolves.toEqual(expect.any(Array));
82
- });
83
-
84
- it("refuses non-private memorials with sensitive fields unless redactions are explicit", async () => {
85
- const runtime = await open();
86
- const analysis = await runtime.analyzeDeath({
87
- companyId: "loop",
88
- companyName: "Loop",
89
- timelineSummaries: ["A customer alice@example.com churned during the final sales push"],
90
- });
91
-
92
- await expect(
93
- runtime.publishMemorial({
94
- analysis,
95
- lessons: await runtime.extractLessons(analysis),
96
- publishLevel: "community",
97
- consentSignatures: ["alice"],
98
- }),
99
- ).rejects.toMatchObject({
100
- capability: "founder-cemetery",
101
- suggestion: expect.stringContaining("redactions"),
102
- });
103
- });
104
- });
package/src/index.ts DELETED
@@ -1,308 +0,0 @@
1
- import { mkdir } from "node:fs/promises";
2
- import { join } from "node:path";
3
- import { requireCapabilityTenant } from "@nebutra/capability-kit";
4
- import { appendCapabilityDebug, readCapabilityDebug } from "@nebutra/capability-kit/debug";
5
- import { ContentStore } from "@nebutra/content-store";
6
- import { assertPublicDisclosureSafe } from "@nebutra/ecosystem-safety";
7
- import { CapabilityError } from "@nebutra/errors";
8
- import { EventLog } from "@nebutra/event-log";
9
- import { assetId } from "@nebutra/generation-context";
10
-
11
- export type CloseMode = "pause" | "archive" | "cemetery";
12
- export type CauseCategory =
13
- | "pmf"
14
- | "runway"
15
- | "fundraising"
16
- | "competition"
17
- | "founder_conflict"
18
- | "pivot";
19
- export type MemorialPublishLevel = "private" | "community" | "public";
20
-
21
- export interface ClosingFlowRequest {
22
- readonly companyId: string;
23
- readonly companyName: string;
24
- readonly founderIds: readonly string[];
25
- }
26
-
27
- export interface ClosingFlow {
28
- readonly companyId: string;
29
- readonly companyName: string;
30
- readonly recommendedMode: "pause";
31
- readonly availableModes: readonly CloseMode[];
32
- readonly requiresCoolingOff: true;
33
- readonly startedAt: string;
34
- }
35
-
36
- export interface DeathAnalysisRequest {
37
- readonly companyId: string;
38
- readonly companyName: string;
39
- readonly timelineSummaries: readonly string[];
40
- }
41
-
42
- export interface DeathCause {
43
- readonly category: CauseCategory;
44
- readonly confidence: number;
45
- readonly evidence: readonly string[];
46
- }
47
-
48
- export interface DeathAnalysis {
49
- readonly companyId: string;
50
- readonly companyName: string;
51
- readonly causes: readonly DeathCause[];
52
- readonly narrative: string;
53
- readonly evidence: readonly string[];
54
- }
55
-
56
- export interface Lesson {
57
- readonly title: string;
58
- readonly lessonText: string;
59
- readonly evidence: readonly string[];
60
- }
61
-
62
- export interface PublishMemorialRequest {
63
- readonly analysis: DeathAnalysis;
64
- readonly lessons: readonly Lesson[];
65
- readonly publishLevel: MemorialPublishLevel;
66
- readonly consentSignatures: readonly string[];
67
- readonly redactions?: readonly string[];
68
- }
69
-
70
- export interface Memorial {
71
- readonly slug: string;
72
- readonly path: string;
73
- readonly publishLevel: MemorialPublishLevel;
74
- readonly coolingOffUntil: string;
75
- readonly eventId: string;
76
- readonly lessons: readonly Lesson[];
77
- readonly redactions: readonly string[];
78
- }
79
-
80
- export interface FounderCemeteryDoctorReport {
81
- readonly capability: "founder-cemetery";
82
- readonly ok: boolean;
83
- readonly checkedAt: string;
84
- readonly features: readonly string[];
85
- readonly suggestion?: string;
86
- }
87
-
88
- export interface FounderCemeteryOptions {
89
- readonly tenantId?: string;
90
- readonly debugRoot?: string;
91
- readonly contentStore?: ContentStore;
92
- readonly eventLog?: EventLog;
93
- }
94
-
95
- function slugify(value: string): string {
96
- return value
97
- .slice(0, 200)
98
- .toLowerCase()
99
- .replace(/[^a-z0-9]{1,200}/g, "-")
100
- .replace(/^-{1,200}|-{1,200}$/g, "")
101
- .slice(0, 64);
102
- }
103
-
104
- function inferCause(evidence: readonly string[]): DeathCause {
105
- const combined = evidence.join("\n").toLowerCase();
106
- if (combined.includes("runway") || combined.includes("cash")) {
107
- return { category: "runway", confidence: 0.74, evidence };
108
- }
109
- if (combined.includes("raise") || combined.includes("fund")) {
110
- return { category: "fundraising", confidence: 0.72, evidence };
111
- }
112
- if (combined.includes("conflict")) {
113
- return { category: "founder_conflict", confidence: 0.7, evidence };
114
- }
115
- if (combined.includes("pivot")) {
116
- return { category: "pmf", confidence: 0.78, evidence };
117
- }
118
- return { category: "pmf", confidence: 0.68, evidence };
119
- }
120
-
121
- function coolingOffDate(): string {
122
- return new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString();
123
- }
124
-
125
- function memorialDisclosureBody(request: PublishMemorialRequest): string {
126
- return [
127
- request.analysis.companyName,
128
- request.analysis.narrative,
129
- request.analysis.evidence.join("\n"),
130
- request.lessons
131
- .map((lesson) => [lesson.title, lesson.lessonText, lesson.evidence.join("\n")].join("\n"))
132
- .join("\n"),
133
- ].join("\n");
134
- }
135
-
136
- export class FounderCemetery {
137
- readonly #tenantId: string;
138
- readonly #debugRoot: string;
139
- readonly #contentStore: ContentStore;
140
- readonly #eventLog: EventLog;
141
-
142
- private constructor(
143
- options: Required<Pick<FounderCemeteryOptions, "tenantId" | "contentStore" | "eventLog">> &
144
- Pick<FounderCemeteryOptions, "debugRoot">,
145
- ) {
146
- this.#tenantId = requireCapabilityTenant({
147
- explicit: options.tenantId,
148
- onMissing: () =>
149
- new CapabilityError("founder-cemetery", "Founder Cemetery requires tenant context", {
150
- suggestion: "Pass tenantId so closure artifacts stay tenant-scoped.",
151
- statusCode: 400,
152
- }),
153
- });
154
- this.#debugRoot = options.debugRoot ?? process.cwd();
155
- this.#contentStore = options.contentStore;
156
- this.#eventLog = options.eventLog;
157
- }
158
-
159
- static async open(
160
- root = ".nebutra/founder-cemetery",
161
- options: Omit<FounderCemeteryOptions, "contentStore" | "eventLog"> = {},
162
- ): Promise<FounderCemetery> {
163
- const tenantId = options.tenantId ?? "local";
164
- await mkdir(root, { recursive: true });
165
- const contentStore = await ContentStore.open(join(root, "content"), { tenantId });
166
- const eventLog = await EventLog.open(join(root, "event-log"), { tenantId });
167
- return new FounderCemetery({ ...options, tenantId, contentStore, eventLog });
168
- }
169
-
170
- async startClosingFlow(request: ClosingFlowRequest): Promise<ClosingFlow> {
171
- const flow: ClosingFlow = {
172
- companyId: request.companyId,
173
- companyName: request.companyName,
174
- recommendedMode: "pause",
175
- availableModes: ["pause", "archive", "cemetery"],
176
- requiresCoolingOff: true,
177
- startedAt: new Date().toISOString(),
178
- };
179
- await this.#debug({ type: "start_closing_flow", tenantId: this.#tenantId, ...flow });
180
- return flow;
181
- }
182
-
183
- async analyzeDeath(request: DeathAnalysisRequest): Promise<DeathAnalysis> {
184
- const evidence =
185
- request.timelineSummaries.length > 0
186
- ? request.timelineSummaries
187
- : ["No timeline summaries were provided."];
188
- const cause = inferCause(evidence);
189
- const analysis: DeathAnalysis = {
190
- companyId: request.companyId,
191
- companyName: request.companyName,
192
- causes: [cause],
193
- evidence,
194
- narrative: `${request.companyName} appears to have stalled around ${cause.category}.`,
195
- };
196
- await this.#debug({
197
- type: "analyze_death",
198
- tenantId: this.#tenantId,
199
- companyId: request.companyId,
200
- category: cause.category,
201
- });
202
- return analysis;
203
- }
204
-
205
- async extractLessons(analysis: DeathAnalysis): Promise<readonly Lesson[]> {
206
- const title =
207
- analysis.causes[0]?.category === "runway"
208
- ? "Validate before scaling burn"
209
- : "Validate demand before widening the pitch";
210
- const lesson: Lesson = {
211
- title,
212
- lessonText: `${analysis.companyName} should preserve the decision context and avoid repeating the highest-impact ${analysis.causes[0]?.category ?? "pmf"} mistake.`,
213
- evidence: analysis.evidence.slice(0, Math.max(2, analysis.evidence.length)),
214
- };
215
- await this.#debug({
216
- type: "extract_lessons",
217
- tenantId: this.#tenantId,
218
- companyId: analysis.companyId,
219
- lessons: 1,
220
- });
221
- return [lesson];
222
- }
223
-
224
- async publishMemorial(request: PublishMemorialRequest): Promise<Memorial> {
225
- if (request.consentSignatures.length === 0) {
226
- throw new CapabilityError("founder-cemetery", "Memorial publication requires consent", {
227
- suggestion:
228
- "Collect founder consent signatures before publishing or keep the company paused.",
229
- statusCode: 400,
230
- });
231
- }
232
- if (request.publishLevel !== "private") {
233
- assertPublicDisclosureSafe({
234
- capability: "founder-cemetery",
235
- content: memorialDisclosureBody(request),
236
- ...(request.redactions !== undefined ? { redactions: request.redactions } : {}),
237
- suggestion: "Review detected private values and pass redactions before publishing.",
238
- });
239
- }
240
-
241
- const slug = slugify(request.analysis.companyName) || request.analysis.companyId;
242
- const path = `cemetery/${slug}.json`;
243
- const memorial = {
244
- slug,
245
- companyId: request.analysis.companyId,
246
- companyName: request.analysis.companyName,
247
- publishLevel: request.publishLevel,
248
- coolingOffUntil: coolingOffDate(),
249
- consentSignatures: request.consentSignatures,
250
- redactions: request.redactions ?? [],
251
- causes: request.analysis.causes,
252
- lessons: request.lessons,
253
- narrative: request.analysis.narrative,
254
- };
255
- const snapshot = `${JSON.stringify(memorial, null, 2)}\n`;
256
- await this.#contentStore.write(path, snapshot);
257
- const eventId = await this.#eventLog.commit({
258
- traceId: assetId("founder_cemetery_publish", slug),
259
- kind: "content_write",
260
- affected: [path],
261
- parent: null,
262
- snapshot: { [path]: snapshot },
263
- });
264
- await this.#debug({
265
- type: "publish_memorial",
266
- tenantId: this.#tenantId,
267
- companyId: request.analysis.companyId,
268
- publishLevel: request.publishLevel,
269
- });
270
- return {
271
- slug,
272
- path,
273
- publishLevel: request.publishLevel,
274
- coolingOffUntil: memorial.coolingOffUntil,
275
- eventId,
276
- lessons: request.lessons,
277
- redactions: memorial.redactions,
278
- };
279
- }
280
-
281
- async doctor(): Promise<FounderCemeteryDoctorReport> {
282
- const report: FounderCemeteryDoctorReport = {
283
- capability: "founder-cemetery",
284
- ok: true,
285
- checkedAt: new Date().toISOString(),
286
- features: ["pause-first", "death-analysis", "lessons", "memorial", "cooling-off"],
287
- suggestion:
288
- "Local memorial artifacts are active; global search and video recap remain lower-layer handoffs.",
289
- };
290
- await this.#debug({ type: "doctor", tenantId: this.#tenantId });
291
- return report;
292
- }
293
-
294
- async close(): Promise<void> {
295
- await this.#contentStore.close();
296
- }
297
-
298
- async #debug(entry: Record<string, unknown>): Promise<void> {
299
- await appendCapabilityDebug("founder-cemetery", entry, { root: this.#debugRoot });
300
- }
301
- }
302
-
303
- export async function readFounderCemeteryDebug(
304
- root = process.cwd(),
305
- limit = 20,
306
- ): Promise<unknown[]> {
307
- return readCapabilityDebug("founder-cemetery", { root, limit });
308
- }
package/tsconfig.json DELETED
@@ -1,9 +0,0 @@
1
- {
2
- "extends": "../../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "outDir": "dist",
5
- "rootDir": "src",
6
- "types": ["node", "vitest/globals"]
7
- },
8
- "include": ["src/**/*.ts"]
9
- }
package/tsup.config.ts DELETED
@@ -1,9 +0,0 @@
1
- import { defineConfig } from "tsup";
2
-
3
- export default defineConfig({
4
- clean: true,
5
- dts: true,
6
- entry: ["src/index.ts", "src/cli.ts"],
7
- format: ["esm"],
8
- sourcemap: true,
9
- });