@namewta/speculo 1.0.7 → 1.0.9

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 (29) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/template/workflows/learning/INDEX.md +2 -2
  4. package/template/workflows/learning/Q-question/Q-question.md +45 -0
  5. package/template/workflows/learning/Q-question/inquiry-template.md +69 -0
  6. package/template/workflows/learning/Q-question/lightweight-course-template.md +31 -0
  7. package/template/workflows/learning/common/rules/artifact-contract.md +1 -0
  8. package/template/workflows/learning/common/rules/questioning-policy.md +38 -0
  9. package/template/workflows/learning/common/rules/teaching-policy.md +2 -0
  10. package/template/workflows/learning/common/skills/socratic-questioning/SKILL.md +31 -0
  11. package/template/workflows/ops/H-host-manage/H-host-manage.md +4 -0
  12. package/template/workflows/ops/README.md +6 -3
  13. package/template/workflows/ops/common/USAGE.md +1 -1
  14. package/template/workflows/ops/common/rules/persistence-and-secrets.md +1 -1
  15. package/template/workflows/ops/common/schemas/host.schema.json +64 -1
  16. package/template/workflows/ops/common/schemas/plan.schema.json +312 -0
  17. package/template/workflows/ops/common/schemas/spec.schema.json +136 -0
  18. package/template/workflows/ops/common/schemas/status.schema.json +142 -0
  19. package/template/workflows/ops/common/service-profiles/elasticsearch.md +13 -0
  20. package/template/workflows/ops/common/service-profiles/redis.md +4 -0
  21. package/template/workflows/ops/common/templates/CONTROLLER-RECORD.md +16 -2
  22. package/template/workflows/ops/common/templates/HOST-README.md +12 -2
  23. package/template/workflows/ops/common/tests/test_ops.mjs +232 -2
  24. package/template/workflows/ops/common/tools/opslib/agent.mjs +44 -13
  25. package/template/workflows/ops/common/tools/opslib/control_files.mjs +57 -0
  26. package/template/workflows/ops/common/tools/opslib/docs.mjs +202 -18
  27. package/template/workflows/ops/common/tools/opslib/execution.mjs +31 -13
  28. package/template/workflows/ops/common/tools/opslib/planner.mjs +108 -14
  29. package/template/workflows/ops/common/tools/opslib/transport.mjs +1 -1
@@ -46,6 +46,61 @@
46
46
  "type": "string",
47
47
  "minLength": 1
48
48
  },
49
+ "registry_slice_digest": {
50
+ "type": "string",
51
+ "minLength": 1
52
+ },
53
+ "registry_scope": {
54
+ "type": "object",
55
+ "properties": {
56
+ "hosts": {
57
+ "type": "array",
58
+ "items": {
59
+ "type": "string"
60
+ }
61
+ },
62
+ "projects": {
63
+ "type": "array",
64
+ "items": {
65
+ "type": "string"
66
+ }
67
+ },
68
+ "deployments": {
69
+ "type": "array",
70
+ "items": {
71
+ "type": "string"
72
+ }
73
+ },
74
+ "allocations": {
75
+ "type": "array",
76
+ "items": {
77
+ "type": "string"
78
+ }
79
+ },
80
+ "bindings": {
81
+ "type": "array",
82
+ "items": {
83
+ "type": "string"
84
+ }
85
+ },
86
+ "policies": {
87
+ "type": "boolean"
88
+ },
89
+ "public_ingress": {
90
+ "type": "boolean"
91
+ }
92
+ },
93
+ "required": [
94
+ "hosts",
95
+ "projects",
96
+ "deployments",
97
+ "allocations",
98
+ "bindings",
99
+ "policies",
100
+ "public_ingress"
101
+ ],
102
+ "additionalProperties": false
103
+ },
49
104
  "registry_revision": {
50
105
  "type": "integer"
51
106
  },
@@ -129,6 +184,64 @@
129
184
  },
130
185
  "required": [],
131
186
  "additionalProperties": false
187
+ },
188
+ "host_services": {
189
+ "type": "array",
190
+ "items": {
191
+ "type": "object",
192
+ "properties": {
193
+ "id": {
194
+ "type": "string",
195
+ "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
196
+ "maxLength": 80
197
+ },
198
+ "kind": {
199
+ "enum": [
200
+ "wireguard",
201
+ "nginx",
202
+ "systemd",
203
+ "probe",
204
+ "other"
205
+ ]
206
+ },
207
+ "unit": {
208
+ "type": "string",
209
+ "minLength": 1
210
+ },
211
+ "listen_port": {
212
+ "type": "integer",
213
+ "minimum": 1,
214
+ "maximum": 65535
215
+ },
216
+ "listen": {
217
+ "type": "array",
218
+ "items": {
219
+ "type": "string",
220
+ "minLength": 1
221
+ }
222
+ },
223
+ "tunnel_address": {
224
+ "type": "string",
225
+ "minLength": 1
226
+ },
227
+ "config_path": {
228
+ "type": "string",
229
+ "minLength": 1
230
+ },
231
+ "public_url": {
232
+ "type": "string",
233
+ "minLength": 1
234
+ },
235
+ "notes": {
236
+ "type": "string"
237
+ }
238
+ },
239
+ "required": [
240
+ "id",
241
+ "kind"
242
+ ],
243
+ "additionalProperties": false
244
+ }
132
245
  }
133
246
  },
134
247
  "required": [
@@ -365,6 +478,87 @@
365
478
  ],
366
479
  "additionalProperties": false
367
480
  },
481
+ "public_ingress": {
482
+ "oneOf": [
483
+ {
484
+ "type": "null"
485
+ },
486
+ {
487
+ "type": "object",
488
+ "properties": {
489
+ "schema_version": {
490
+ "const": 1
491
+ },
492
+ "title": {
493
+ "type": "string",
494
+ "minLength": 1
495
+ },
496
+ "path": {
497
+ "type": "string",
498
+ "minLength": 1
499
+ },
500
+ "not_the_same_as": {
501
+ "type": "string"
502
+ },
503
+ "mappings": {
504
+ "type": "array",
505
+ "items": {
506
+ "type": "object",
507
+ "properties": {
508
+ "public": {
509
+ "type": "string",
510
+ "minLength": 1
511
+ },
512
+ "layer4": {
513
+ "type": "string"
514
+ },
515
+ "via": {
516
+ "type": "array",
517
+ "items": {
518
+ "type": "string"
519
+ }
520
+ },
521
+ "backend": {
522
+ "type": "string",
523
+ "minLength": 1
524
+ },
525
+ "backend_deployment": {
526
+ "type": "string"
527
+ }
528
+ },
529
+ "required": [
530
+ "public",
531
+ "backend"
532
+ ],
533
+ "additionalProperties": false
534
+ }
535
+ },
536
+ "open_http_checklist": {
537
+ "type": "array",
538
+ "items": {
539
+ "type": "string",
540
+ "minLength": 1
541
+ }
542
+ },
543
+ "forbidden_ports": {
544
+ "type": "array",
545
+ "items": {
546
+ "type": "integer",
547
+ "minimum": 1,
548
+ "maximum": 65535
549
+ }
550
+ }
551
+ },
552
+ "required": [
553
+ "schema_version",
554
+ "title",
555
+ "path",
556
+ "mappings"
557
+ ],
558
+ "additionalProperties": false
559
+ }
560
+ ]
561
+ },
368
562
  "updated_at": {
369
563
  "type": [
370
564
  "string",
@@ -461,6 +655,64 @@
461
655
  },
462
656
  "required": [],
463
657
  "additionalProperties": false
658
+ },
659
+ "host_services": {
660
+ "type": "array",
661
+ "items": {
662
+ "type": "object",
663
+ "properties": {
664
+ "id": {
665
+ "type": "string",
666
+ "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
667
+ "maxLength": 80
668
+ },
669
+ "kind": {
670
+ "enum": [
671
+ "wireguard",
672
+ "nginx",
673
+ "systemd",
674
+ "probe",
675
+ "other"
676
+ ]
677
+ },
678
+ "unit": {
679
+ "type": "string",
680
+ "minLength": 1
681
+ },
682
+ "listen_port": {
683
+ "type": "integer",
684
+ "minimum": 1,
685
+ "maximum": 65535
686
+ },
687
+ "listen": {
688
+ "type": "array",
689
+ "items": {
690
+ "type": "string",
691
+ "minLength": 1
692
+ }
693
+ },
694
+ "tunnel_address": {
695
+ "type": "string",
696
+ "minLength": 1
697
+ },
698
+ "config_path": {
699
+ "type": "string",
700
+ "minLength": 1
701
+ },
702
+ "public_url": {
703
+ "type": "string",
704
+ "minLength": 1
705
+ },
706
+ "notes": {
707
+ "type": "string"
708
+ }
709
+ },
710
+ "required": [
711
+ "id",
712
+ "kind"
713
+ ],
714
+ "additionalProperties": false
715
+ }
464
716
  }
465
717
  },
466
718
  "required": [
@@ -1000,6 +1252,8 @@
1000
1252
  "expires_at",
1001
1253
  "controller_id",
1002
1254
  "registry_digest",
1255
+ "registry_slice_digest",
1256
+ "registry_scope",
1003
1257
  "registry_revision",
1004
1258
  "hosts",
1005
1259
  "transport_digests",
@@ -1092,6 +1346,64 @@
1092
1346
  },
1093
1347
  "required": [],
1094
1348
  "additionalProperties": false
1349
+ },
1350
+ "host_services": {
1351
+ "type": "array",
1352
+ "items": {
1353
+ "type": "object",
1354
+ "properties": {
1355
+ "id": {
1356
+ "type": "string",
1357
+ "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
1358
+ "maxLength": 80
1359
+ },
1360
+ "kind": {
1361
+ "enum": [
1362
+ "wireguard",
1363
+ "nginx",
1364
+ "systemd",
1365
+ "probe",
1366
+ "other"
1367
+ ]
1368
+ },
1369
+ "unit": {
1370
+ "type": "string",
1371
+ "minLength": 1
1372
+ },
1373
+ "listen_port": {
1374
+ "type": "integer",
1375
+ "minimum": 1,
1376
+ "maximum": 65535
1377
+ },
1378
+ "listen": {
1379
+ "type": "array",
1380
+ "items": {
1381
+ "type": "string",
1382
+ "minLength": 1
1383
+ }
1384
+ },
1385
+ "tunnel_address": {
1386
+ "type": "string",
1387
+ "minLength": 1
1388
+ },
1389
+ "config_path": {
1390
+ "type": "string",
1391
+ "minLength": 1
1392
+ },
1393
+ "public_url": {
1394
+ "type": "string",
1395
+ "minLength": 1
1396
+ },
1397
+ "notes": {
1398
+ "type": "string"
1399
+ }
1400
+ },
1401
+ "required": [
1402
+ "id",
1403
+ "kind"
1404
+ ],
1405
+ "additionalProperties": false
1406
+ }
1095
1407
  }
1096
1408
  },
1097
1409
  "required": [
@@ -102,6 +102,64 @@
102
102
  },
103
103
  "required": [],
104
104
  "additionalProperties": false
105
+ },
106
+ "host_services": {
107
+ "type": "array",
108
+ "items": {
109
+ "type": "object",
110
+ "properties": {
111
+ "id": {
112
+ "type": "string",
113
+ "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
114
+ "maxLength": 80
115
+ },
116
+ "kind": {
117
+ "enum": [
118
+ "wireguard",
119
+ "nginx",
120
+ "systemd",
121
+ "probe",
122
+ "other"
123
+ ]
124
+ },
125
+ "unit": {
126
+ "type": "string",
127
+ "minLength": 1
128
+ },
129
+ "listen_port": {
130
+ "type": "integer",
131
+ "minimum": 1,
132
+ "maximum": 65535
133
+ },
134
+ "listen": {
135
+ "type": "array",
136
+ "items": {
137
+ "type": "string",
138
+ "minLength": 1
139
+ }
140
+ },
141
+ "tunnel_address": {
142
+ "type": "string",
143
+ "minLength": 1
144
+ },
145
+ "config_path": {
146
+ "type": "string",
147
+ "minLength": 1
148
+ },
149
+ "public_url": {
150
+ "type": "string",
151
+ "minLength": 1
152
+ },
153
+ "notes": {
154
+ "type": "string"
155
+ }
156
+ },
157
+ "required": [
158
+ "id",
159
+ "kind"
160
+ ],
161
+ "additionalProperties": false
162
+ }
105
163
  }
106
164
  },
107
165
  "required": [
@@ -674,6 +732,10 @@
674
732
  "type": "integer",
675
733
  "minimum": 256,
676
734
  "maximum": 511
735
+ },
736
+ "rollback": {
737
+ "type": "string",
738
+ "minLength": 1
677
739
  }
678
740
  },
679
741
  "required": [
@@ -1019,6 +1081,80 @@
1019
1081
  "external-mutation",
1020
1082
  "production-critical"
1021
1083
  ]
1084
+ },
1085
+ "public_ingress": {
1086
+ "type": "object",
1087
+ "properties": {
1088
+ "schema_version": {
1089
+ "const": 1
1090
+ },
1091
+ "title": {
1092
+ "type": "string",
1093
+ "minLength": 1
1094
+ },
1095
+ "path": {
1096
+ "type": "string",
1097
+ "minLength": 1
1098
+ },
1099
+ "not_the_same_as": {
1100
+ "type": "string"
1101
+ },
1102
+ "mappings": {
1103
+ "type": "array",
1104
+ "items": {
1105
+ "type": "object",
1106
+ "properties": {
1107
+ "public": {
1108
+ "type": "string",
1109
+ "minLength": 1
1110
+ },
1111
+ "layer4": {
1112
+ "type": "string"
1113
+ },
1114
+ "via": {
1115
+ "type": "array",
1116
+ "items": {
1117
+ "type": "string"
1118
+ }
1119
+ },
1120
+ "backend": {
1121
+ "type": "string",
1122
+ "minLength": 1
1123
+ },
1124
+ "backend_deployment": {
1125
+ "type": "string"
1126
+ }
1127
+ },
1128
+ "required": [
1129
+ "public",
1130
+ "backend"
1131
+ ],
1132
+ "additionalProperties": false
1133
+ }
1134
+ },
1135
+ "open_http_checklist": {
1136
+ "type": "array",
1137
+ "items": {
1138
+ "type": "string",
1139
+ "minLength": 1
1140
+ }
1141
+ },
1142
+ "forbidden_ports": {
1143
+ "type": "array",
1144
+ "items": {
1145
+ "type": "integer",
1146
+ "minimum": 1,
1147
+ "maximum": 65535
1148
+ }
1149
+ }
1150
+ },
1151
+ "required": [
1152
+ "schema_version",
1153
+ "title",
1154
+ "path",
1155
+ "mappings"
1156
+ ],
1157
+ "additionalProperties": false
1022
1158
  }
1023
1159
  },
1024
1160
  "required": [
@@ -194,6 +194,16 @@
194
194
  ],
195
195
  "additionalProperties": false
196
196
  },
197
+ "public_ingress": {
198
+ "oneOf": [
199
+ {
200
+ "type": "null"
201
+ },
202
+ {
203
+ "$ref": "#/$defs/public_ingress"
204
+ }
205
+ ]
206
+ },
197
207
  "updated_at": {
198
208
  "type": [
199
209
  "string",
@@ -290,6 +300,64 @@
290
300
  },
291
301
  "required": [],
292
302
  "additionalProperties": false
303
+ },
304
+ "host_services": {
305
+ "type": "array",
306
+ "items": {
307
+ "type": "object",
308
+ "properties": {
309
+ "id": {
310
+ "type": "string",
311
+ "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
312
+ "maxLength": 80
313
+ },
314
+ "kind": {
315
+ "enum": [
316
+ "wireguard",
317
+ "nginx",
318
+ "systemd",
319
+ "probe",
320
+ "other"
321
+ ]
322
+ },
323
+ "unit": {
324
+ "type": "string",
325
+ "minLength": 1
326
+ },
327
+ "listen_port": {
328
+ "type": "integer",
329
+ "minimum": 1,
330
+ "maximum": 65535
331
+ },
332
+ "listen": {
333
+ "type": "array",
334
+ "items": {
335
+ "type": "string",
336
+ "minLength": 1
337
+ }
338
+ },
339
+ "tunnel_address": {
340
+ "type": "string",
341
+ "minLength": 1
342
+ },
343
+ "config_path": {
344
+ "type": "string",
345
+ "minLength": 1
346
+ },
347
+ "public_url": {
348
+ "type": "string",
349
+ "minLength": 1
350
+ },
351
+ "notes": {
352
+ "type": "string"
353
+ }
354
+ },
355
+ "required": [
356
+ "id",
357
+ "kind"
358
+ ],
359
+ "additionalProperties": false
360
+ }
293
361
  }
294
362
  },
295
363
  "required": [
@@ -766,6 +834,80 @@
766
834
  "network"
767
835
  ],
768
836
  "additionalProperties": false
837
+ },
838
+ "public_ingress": {
839
+ "type": "object",
840
+ "properties": {
841
+ "schema_version": {
842
+ "const": 1
843
+ },
844
+ "title": {
845
+ "type": "string",
846
+ "minLength": 1
847
+ },
848
+ "path": {
849
+ "type": "string",
850
+ "minLength": 1
851
+ },
852
+ "not_the_same_as": {
853
+ "type": "string"
854
+ },
855
+ "mappings": {
856
+ "type": "array",
857
+ "items": {
858
+ "type": "object",
859
+ "properties": {
860
+ "public": {
861
+ "type": "string",
862
+ "minLength": 1
863
+ },
864
+ "layer4": {
865
+ "type": "string"
866
+ },
867
+ "via": {
868
+ "type": "array",
869
+ "items": {
870
+ "type": "string"
871
+ }
872
+ },
873
+ "backend": {
874
+ "type": "string",
875
+ "minLength": 1
876
+ },
877
+ "backend_deployment": {
878
+ "type": "string"
879
+ }
880
+ },
881
+ "required": [
882
+ "public",
883
+ "backend"
884
+ ],
885
+ "additionalProperties": false
886
+ }
887
+ },
888
+ "open_http_checklist": {
889
+ "type": "array",
890
+ "items": {
891
+ "type": "string",
892
+ "minLength": 1
893
+ }
894
+ },
895
+ "forbidden_ports": {
896
+ "type": "array",
897
+ "items": {
898
+ "type": "integer",
899
+ "minimum": 1,
900
+ "maximum": 65535
901
+ }
902
+ }
903
+ },
904
+ "required": [
905
+ "schema_version",
906
+ "title",
907
+ "path",
908
+ "mappings"
909
+ ],
910
+ "additionalProperties": false
769
911
  }
770
912
  }
771
913
  }
@@ -0,0 +1,13 @@
1
+ # elasticsearch 服务档案
2
+
3
+ 提供者是独立 elasticsearch 项目(或用户选定的 kebab ID),`service_type` 用实际产品名,不伪装成内置分配 adapter。image 固定摘要。数据在 `data/elasticsearch/data`,日志在 `logs/elasticsearch`;容器内 data/logs 路径按所用镜像 VOLUME 显式 bind,禁止匿名卷。
4
+
5
+ 官方 Elasticsearch 8 会在启动时写 `elasticsearch.keystore`(临时文件 `elasticsearch.keystore.tmp`)。把 config/data/logs bind 到项目目录后:
6
+
7
+ - 容器用户必须能写 data 与实际 keystore 目录;不要把 keystore 放进只读 config bind。
8
+ - 仅当镜像仍必须写容器根文件系统时,才允许 `read_only: false`,并提供不少于 12 字符的 `writable_root_justification`。默认仍是只读根。
9
+ - `config/` 与 `*.conf`/`*.yml` 默认文件模式 0644,供非 root 镜像用户读取;config/env bind 必须 `read_only: true`。
10
+
11
+ 生产健康检查不能只用 docker-proxy 上的 TCP。Compose 服务应声明 `healthcheck`;`compose --wait` 之后执行器要求 `State.Status=running`、非 OOMKilled/Restarting,若存在 Health 则必须 `healthy`。
12
+
13
+ 没有内置集群分配/账号 adapter。跨项目访问通过 existing + 实际授权探测,或专用 host/project 脚本;不能把「能 compose up」写成已具备逻辑资源恢复能力。备份使用该版本可验证的 snapshot/仓库工具;单 APP 回滚不得恢复整个集群。
@@ -2,6 +2,10 @@
2
2
 
3
3
  提供者独立 redis-main 项目,service_type=redis,service.compose_service 指向实际服务。数据在 data/redis/instance;ACL 文件配置为 data/redis/acl/users.acl(service.acl_persistence 必须完全匹配),容器 ACL 写入路径必须映射到这个项目数据目录,不能将 ACL SAVE 写到只读 config。
4
4
 
5
+ `config/redis.conf` 以及 `*.acl` 默认文件模式 0644。Redis 镜像若以非 root 用户运行,0600 root 配置会导致 `can't open config file` 后重启循环。config bind 必须只读;可写数据只在 data/logs/run。不要为了读配置而把整个容器根改成可写。
6
+
5
7
  每个 APP 使用不同 ACL username、prefix 和凭据;禁用/限制危险管理命令,内置分配使用受限命令类别。必须核验真实客户端兼容性、ACL SAVE 和新账号认证。prefix/数字 DB 不等于独立内存/CPU/备份恢复边界;要求强隔离时部署专用实例。
6
8
 
9
+ 生产健康检查使用 redis-cli PING 或镜像 healthcheck,不能把 docker-proxy 的 TCP listen 当成进程可用。无 healthcheck 时 `compose --wait` 只表示容器已创建。
10
+
7
11
  持久化 AOF/RDB 属于业务数据不是可随意清理的日志。公共实例恢复影响所有消费者,需要整体维护批准。