@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
package/README.md CHANGED
@@ -72,7 +72,7 @@ After initialization, the target project gains the following AI agent-callable a
72
72
 
73
73
  | Workflow | Work Entries | Description |
74
74
  |---|---:|---|
75
- | **learning** | 7 | Evidence-aware learning for projects, products, subjects, languages, and skills: complete 30–40 minute plain-language lessons, single-file homework review, optional retention review, and provenance-preserving topic synthesis |
75
+ | **learning** | 8 | Evidence-aware learning for projects, products, subjects, languages, and skills: complete 30–40 minute plain-language lessons, Socratic inquiry lessons, single-file homework review, optional retention review, and provenance-preserving topic synthesis |
76
76
  | **specdev** | 14 | Local-first specification-driven development: archive, code review, diagnosis, grilling, implementation, setup, learning, goal planning, prototyping, architecture review, specs, tickets, triage, and wayfinding |
77
77
  | **ops** | 3 | Host inventory and project deployment: initialize, host manage, and APP/shared-service deploy with dual documentation |
78
78
  | **person** | 2 | Persona-methodology and rigorous deliberation workflows (Mao Zedong Cognitive OS; Bidirectional Steelman Deliberation) |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@namewta/speculo",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "Workflow-packaged AI collaboration assets with state-safe refresh tooling.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -3,8 +3,8 @@ id: learning
3
3
  type: workflow
4
4
  workflow: learning
5
5
  name: Learning Workflow
6
- description: 以完整、通俗、多表示的课程,单文件作业评审、可选延迟复习和带溯源的主题综合,持续建立个人 Markdown 知识库。
7
- keywords: [learning, 学习, 教学, 作业, 复习, 综合, 知识, eli5]
6
+ description: 以完整、通俗、多表示的课程,苏格拉底问答课、单文件作业评审、可选延迟复习和带溯源的主题综合,持续建立个人 Markdown 知识库。
7
+ keywords: [learning, 学习, 教学, 苏格拉底, 反问, 作业, 复习, 综合, 知识, eli5]
8
8
  ---
9
9
 
10
10
  # Learning Index
@@ -0,0 +1,45 @@
1
+ ---
2
+ id: learning/question
3
+ type: workflow-entry
4
+ workflow: learning
5
+ name: 苏格拉底问答课
6
+ description: 以一批约 5 题激活已知与未知,学习者作答后追加详细讲解、纠错与深化;一批生成一节 inquiry-lesson。无 Change 时可自行创建 lightweight inquiry Change。不自动串联 L/H/R。
7
+ keywords: [反问, 苏格拉底, socratic, inquiry, 提问课, questioning, 激活, 问答课]
8
+ ---
9
+
10
+ # 苏格拉底问答课
11
+
12
+ > 激活本 Work 后,先读取 `<Path>{roots.workflows}/learning/README.md</Path>`。
13
+
14
+ ## 读取范围
15
+
16
+ 1. 先读取 `<Path>{roots.workflows}/learning/README.md</Path>` 与当前 Work 的状态入口。
17
+ 2. 再读取 `<Path>{roots.workflows}/learning/common/rules/activation-and-memory.md</Path>`,按当前分支、状态和关键词定位最小相关工件。
18
+ 3. 只在本 Work 明确要求恢复、冲突、执行安全、创建 Change 或归档证据时扩展为全量读取;缺少匹配证据或 owner/gateway 时停止受影响分支。
19
+
20
+ ## 流程
21
+
22
+ 1. 解析 roots 与 Learning v2 状态。若尚无 `status.json` / `locations.json`,先按 I-init-setup 写入空状态骨架,不创建知识条目。
23
+ 2. 若没有可用 Change:根据用户主题创建 lightweight inquiry Change `YYYY-MM-DD-<kebab-topic>`,写入 `INDEX.md`、最小 `course.md`/`baseline.md`/`sources.md`、`inquiry/INDEX.md`、`learning-log.md` 和 `.status.json`(`phase=teaching`,`current_work=learning/question`)。不假装已完成 A-assess-and-plan 的完整课程地图。
24
+ 3. 若已有 Change:按 Activation 合同只读取对应 course/OBJ/Lesson/baseline/notes/inquiry 索引;不整读 archive 或其他 Change。
25
+ 4. 读取 `<Path>{roots.workflows}/learning/common/skills/socratic-questioning/SKILL.md</Path>` 与 `<Path>{roots.workflows}/learning/common/rules/questioning-policy.md</Path>`。按用户指定教法或默认 `socratic` 配方生成一批约 5 题。
26
+ 5. 创建 `inquiry/IQ-<NNN>-<slug>-batch-NN.md`:元数据、Q1…Q5、空白 A1…A5、`Response: pending`。更新 `inquiry/INDEX.md`。不得把答案写入题目。
27
+ 6. 学习者填写 A1…并写入精确行 `Response: ready` 后再次激活本 Work。校验回答原文与标记,冻结 Q/A。
28
+ 7. 只在同一文件末尾追加 `## Teaching` 与 `## Inquiry Lesson`。Teaching 逐题给出思路复原、`aligned|partial|off|uncertain`、中文详解、`Explain (English)`、纠错路径、先前未覆盖知识和来源锚点。Inquiry Lesson 把本批 5 题收成一节短课单元,并以 keep-alive 钩子指向下一批、缺失 OBJ、L、H 或 R。将 `Response:` 更新为 `closed`。
29
+ 8. 更新 `learning-log.md` 与 Change `.status.json`:`works_run` 追加 `learning/question`,清空 `current_work`。不写 mastered,不写入 `lessons/` 或 `homework/`,不自动激活其他 Work。重答必须新建 batch 文件并链接旧文件。
30
+
31
+ ## 完成标准
32
+
33
+ - 一批默认 5 题;数量可由用户指定,但必须 Q/A 成对且连续编号;
34
+ - `Response: pending|ready|closed` 状态可审计;ready 之前不得出现 Teaching / Inquiry Lesson;
35
+ - Teaching 是授课讲解,不是 H 的评分 Review,不得使用 `Submission` 或 `verdict: correct|partial|incorrect` 字段名;
36
+ - 5 题生成一节 Inquiry Lesson;完整 30–40 分钟讲义仍归 L-lesson;
37
+ - 无 Change 时本 Work 可自行创建 lightweight inquiry Change,不得因缺少 A 产物而拒绝开问;
38
+ - 真新手或高元素交互时必须提供降级探针或建议先走 L-lesson。
39
+
40
+ ## 子文件
41
+
42
+ - 问答课模板:`<Path>{roots.workflows}/learning/Q-question/inquiry-template.md</Path>`
43
+ - 轻量课程模板:`<Path>{roots.workflows}/learning/Q-question/lightweight-course-template.md</Path>`
44
+ - 提问政策:`<Path>{roots.workflows}/learning/common/rules/questioning-policy.md</Path>`
45
+ - 提问引擎:`<Path>{roots.workflows}/learning/common/skills/socratic-questioning/SKILL.md</Path>`
@@ -0,0 +1,69 @@
1
+ ---
2
+ inquiry_id: IQ-<NNN>
3
+ batch: 01
4
+ lesson_unit_id: IQ-<NNN>
5
+ objective_ids: [OBJ-01]
6
+ question_count: 5
7
+ teaching_method: socratic
8
+ expression_level: plain
9
+ coverage_depth: standard
10
+ source_ids: [S-001]
11
+ created_at: <ISO-8601>
12
+ ---
13
+
14
+ # 苏格拉底问答课:<主题>
15
+
16
+ ## 引用
17
+
18
+ - Change:`<stable change id and current locator>`
19
+ - 目标:`<OBJ ids>`
20
+ - 教法:`socratic | 5e-recipe | feynman | productive-failure | custom`
21
+ - Skill:`socratic-questioning`
22
+
23
+ ## Questions
24
+
25
+ ### Q1 — 澄清与定义
26
+
27
+ <问题>
28
+
29
+ ### Q2 — 机制与证据
30
+
31
+ <问题>
32
+
33
+ ### Q3 — 假设与反例
34
+
35
+ <问题>
36
+
37
+ ### Q4 — 迁移与视角
38
+
39
+ <问题>
40
+
41
+ ### Q5 — 元问题与下一步
42
+
43
+ <问题>
44
+
45
+ ## Learner Answers
46
+
47
+ ### A1
48
+
49
+ <在此填写,不要改写 Q1>
50
+
51
+ ### A2
52
+
53
+ <在此填写,不要改写 Q2>
54
+
55
+ ### A3
56
+
57
+ <在此填写,不要改写 Q3>
58
+
59
+ ### A4
60
+
61
+ <在此填写,不要改写 Q4>
62
+
63
+ ### A5
64
+
65
+ <在此填写,不要改写 Q5>
66
+
67
+ Response: pending
68
+
69
+ <!-- Q 在 Response: ready 后只能追加 Teaching 与 Inquiry Lesson;不得改写以上内容。不得使用 Submission 或 verdict。 -->
@@ -0,0 +1,31 @@
1
+ # 课程设计:<主题>(inquiry-first)
2
+
3
+ 本 Change 由 `Q-question` 在没有现成课程时创建。它只冻结主题、可观察目标和开问范围,不假装 `A-assess-and-plan` 已完成完整 Lesson 地图。
4
+
5
+ ## 目标与期望效果
6
+
7
+ | ID | 可观察目标 | 关键性 | 前置 OBJ | 证据类型 | Inquiry | Lesson | Homework |
8
+ | --- | --- | --- | --- | --- | --- | --- | --- |
9
+ | OBJ-01 | `<能用自己的话解释什么>` | 是 | `<none>` | `<解释/边界/下一步>` | IQ-001 | 可选 | 可选 |
10
+
11
+ ## 学习者与表达/深度配置
12
+
13
+ | 字段 | 值 |
14
+ | --- | --- |
15
+ | expression_level | `plain` |
16
+ | coverage_depth | `standard` |
17
+ | 来源 | inquiry-first;完整背景由后续 A 补全 |
18
+
19
+ ## 课程地图
20
+
21
+ 先用苏格拉底问答课激活已知与未知;需要 30–40 分钟完整讲义时再激活 `L-lesson`,需要正式测评时再激活 `H-homework`。
22
+
23
+ ## 成功证据与范围外
24
+
25
+ - 成功:至少一批 `Response: closed` 的 Inquiry Lesson,并留下 keep-alive 钩子。
26
+ - 范围外:不在本 Change 写入 `lessons/` 或 `homework/`,不宣称 mastered。
27
+
28
+ ## Revision 记录
29
+
30
+ | 时间 | 变化 | 原因 | 是否升级为完整 A 课程 |
31
+ | --- | --- | --- | --- |
@@ -5,6 +5,7 @@
5
5
  | `course.md`、`background/`、`baseline.md`、`sources.md`、Change `INDEX.md` | A-assess-and-plan | 目标、宏观基础、原始基线、来源和课程地图;实质修改留 revision |
6
6
  | `lessons/` | L-lesson | 完整 Lesson 和 Lesson INDEX;不写作业答案或掌握结论 |
7
7
  | `homework/` | H-homework + learner | H 写问题/评审,learner 写 A;提交后只追加 Review,旧 attempt 不可改写 |
8
+ | `inquiry/` | Q-question + learner | Q 写问题/Teaching/Inquiry Lesson,learner 写 A;`Response: ready` 后只追加讲解,旧 batch 不可改写;不写入 `lessons/` 或 `homework/` |
8
9
  | `review/` | R-review | 延迟保持题、原始回答、证据和复习日期 |
9
10
  | `children/<id>/` | child Work | 子 Change 原有工件;父只负责根锁、路由、位置登记 |
10
11
  | `synthesis/`、topic context | C-consolidate | claim 级综合、冲突、空白、provenance 和版本;不得覆盖原料 |
@@ -0,0 +1,38 @@
1
+ # 苏格拉底问答政策
2
+
3
+ 反问批次只允许写在 `Q-question` 拥有的 `inquiry/` 内。`L-lesson` 仍然禁止 Q/A、答案、verdict、mastered。本政策改出题与讲解,不改 H 的 `Submission` 协议。
4
+
5
+ ## 配方
6
+
7
+ 用户可指定 `teaching_method`;缺省为 `socratic`。配方只改变 Q1–Q5 的写法,不改变文件协议。
8
+
9
+ | teaching_method | Q1 | Q2 | Q3 | Q4 | Q5 |
10
+ | --- | --- | --- | --- | --- | --- |
11
+ | `socratic` | 澄清/定义 | 机制/证据 | 假设与反例 | 迁移/他者视角 | 元问题/下一步 |
12
+ | `5e-recipe` | Engage | Explore | Explain-prompt | Elaborate | Evaluate-as-question |
13
+ | `feynman` | 用自己的话定义 | 举生活例子 | 指出类比失效 | 教给外行 | 还缺哪一块 |
14
+ | `productive-failure` | 未教过的难题 | 你怎么试 | 卡在哪 | 规范解会怎么走 | 和你的差在哪 |
15
+ | 用户自定 | 编译进同一 5 槽,缺槽用 `socratic` 补 |
16
+
17
+ 每题标注 `objective_id`、`bloom_level`、`socratic_move`、`expected_evidence`、`difficulty`。数量默认 5,可由用户改,但必须 Q/A 成对连续。
18
+
19
+ ## 文件协议
20
+
21
+ - 出题文件含空 A 与精确行 `Response: pending`。
22
+ - 学习者作答后写 `Response: ready`,再次激活 Q。
23
+ - Teaching / Inquiry Lesson 只能追加在 ready 之后;不得改写 Q/A。
24
+ - 闭环后 `Response: closed`。重答新建 `IQ-…-batch-NN`,旧文件只读。
25
+ - 禁止 `Submission:`、禁止 H 的 `verdict: correct|partial|incorrect` 字段名。教学判定用 `aligned|partial|off|uncertain`。
26
+ - 禁止写入 `lessons/` 或 `homework/`。
27
+
28
+ ## 讲解与 keep-alive
29
+
30
+ `## Teaching` 每题必须有:思路复原、判定、中文详解、`Explain (English)`、纠错路径、先前未覆盖知识、来源锚点。
31
+ `## Inquiry Lesson` 把本批收成一节短课:地图、机制、边界、稳定误区、下一步激活钩子。
32
+ 每一份 Teaching 结尾必须有 keep-alive 钩子(下一批种子、缺失 OBJ、建议 L/H/R),不得把本批写成终点。
33
+
34
+ ## 新手逃逸与 Change
35
+
36
+ baseline 显示真新手或主题元素交互很高时,先降难度探针,或建议激活 `L-lesson` 再建模型。不强制 question-first。卡住连续三题仍无进展时给脚手架,而不是直接灌完整答案进 Q 文本。
37
+
38
+ 无可用 Change 且用户已激活本 Work 时,允许创建 lightweight inquiry Change;不得因缺少 A 产物而拒绝开问,也不得复活已退役的 `Q-quiz`。
@@ -13,3 +13,5 @@
13
13
  ASCII、Markdown table、公式或可选外链图片可以组合使用;每个视觉必须有 caption、alt 和附近的完整文字等价物,外链失效不能阻塞理解。`sources.md` 和 Lesson source table 记录 URL、标题、定位、访问日期、claim 映射、可信度和不确定性;无法验证的内容明确标为 open/uncertain。
14
14
 
15
15
  Lesson 可以有非评分 pause/self-check,但不含 Q/A、答案、分数、verdict 或 mastered 字段。
16
+
17
+ 苏格拉底 / 反问批次只允许出现在 `Q-question` 拥有的 `inquiry/` 内;`L-lesson` 不得写 Q/A。Q 的讲解遵循本政策的表达与来源规则,但不占用 30–40 分钟 Lesson 预算。
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: socratic-questioning
3
+ description: 苏格拉底问答、反问授课或用提问教;当学习者卡住、不知道下一步、指定提问/5E/费曼/生产性失败,或 Q-question 需要出题与讲解配方时使用。
4
+ ---
5
+
6
+ # Socratic Questioning
7
+
8
+ 本 skill 只生成提问、诊断与讲解文本。工件所有权仍归 `Q-question` 的 `inquiry/`;不得写入 `lessons/` 或 `homework/`。
9
+
10
+ 1. 只由 `Q-question` 调用。按稳定 Change ID 读取当前 locator,禁止依赖旧路径。无 Change 时允许 Q 创建 lightweight inquiry Change,不假装 A 已完成。
11
+ 2. 读取调用方给出的 topic、OBJ、baseline、指定 `teaching_method` 和已有 inquiry 索引;按 `<Path>{roots.workflows}/learning/common/rules/questioning-policy.md</Path>` 选择配方,不要整读 archive。
12
+ 3. 先判断能否提问:真新手或高元素交互时返回降级探针或「先走 L-lesson」建议,而不是硬出机制题。
13
+ 4. 默认 `socratic` 五槽:澄清、机制证据、假设反例、迁移视角、元问题/下一步。用户指定 `5e-recipe` / `feynman` / `productive-failure` / custom 时只改题目,不改 inquiry 文件协议。
14
+ 5. 一批写入 `inquiry/IQ-*.md`:Q1–Q5、空 A、`Response: pending`。`Response: ready` 后只追加 Teaching 与 Inquiry Lesson;不改写答案,不写 `lessons/`、`homework/`、mastered、`Submission`、`verdict`。
15
+ 6. Teaching 每题含思路复原、`aligned|partial|off|uncertain`、中文详解、`Explain (English)`、纠错、未见知识、来源。Inquiry Lesson 把 5 题收成一课并给 keep-alive 钩子。需要完整 30–40 分钟讲义或正式测评时只返回路由,不自动激活 L/H/R。
16
+
17
+ ## 题槽
18
+
19
+ | 槽 | 动作 | Paul 类 |
20
+ | --- | --- | --- |
21
+ | Q1 | 澄清/定义 | clarification |
22
+ | Q2 | 机制/证据 | evidence |
23
+ | Q3 | 假设/反例 | assumptions |
24
+ | Q4 | 迁移/视角 | viewpoints |
25
+ | Q5 | 元问题/下一步 | question-the-question |
26
+
27
+ ## 完成标准
28
+
29
+ - 一批 Q/A 成对;讲解在作答之后;
30
+ - 指定教法只改变题目,不改变 Response 协议;
31
+ - 输出可被 Q-question 直接追加进 `IQ-*.md`。
@@ -27,4 +27,8 @@ Docker 缺失使用经审核且版本固定的 Linux Engine 安装配方,完
27
27
 
28
28
  主机维护影响现存 APP/公共服务消费者时必须明确 acknowledged_consumers。完整计划列出下载、系统控制文件、服务重启、默认恢复和验证;执行通过后刷新主机双边记录。
29
29
 
30
+ `write-control` 精确绝对路径例外:内置 `/etc/docker/daemon.json` 与 `/etc/systemd/system/ops-*.service`;经审批还可声明 nginx conf.d、wireguard 配置、以及非 `ops-` 前缀的 systemd 单元。声明路径必须带理由、回滚说明和事后验证,不是任意 `/etc` 写权限。`sshd`/`docker`/`containerd` 等核心单元拒绝。业务数据路径没有该例外。
31
+
32
+ 主机级入口(WireGuard、Nginx、探测页)写入 `resource_updates.hosts[].host_services`,生成器输出 `knowledge/host-services.json` 并进入服务一览表。跨主机公网入口写入 spec `public_ingress`,生成 `knowledge/public-ingress.json` 与「公网访问内网」章节。这些不是假的 APP 部署。`write-file` 不得覆盖生成器负责的 `README.md` / `DEPLOYMENTS.md` / `knowledge/host-services.json` / `knowledge/public-ingress.json` / `knowledge/INDEX.md`。
33
+
30
34
  命令合同:`<Path>{roots.workflows}/ops/common/USAGE.md</Path>`;所有执行通过 ops.mjs,不能绕过计划审批直接拼接命令调用主机。
@@ -28,6 +28,9 @@ host_root/
28
28
  DEPLOYMENTS.md
29
29
  docs/standards/DEPLOYMENT-STANDARD.md
30
30
  knowledge/
31
+ INDEX.md
32
+ host-services.json # 主机级入口:WireGuard/Nginx/探测,不是 APP 部署
33
+ public-ingress.json # 跨主机公网→内网映射;入口与出口不是同一条连接
31
34
  _host/ # 主机证据、安装器、有限缓存和隔离
32
35
  _runtime/docker/ # 仅经准备/显式迁移的 Docker Engine
33
36
  app-a/
@@ -62,15 +65,15 @@ host_root/
62
65
 
63
66
  ## 状态字段
64
67
 
65
- schema_version=3;hosts、projects、deployments、allocations、bindings、releases、controller、policies、revision、updated_at。
68
+ schema_version=3;hosts、projects、deployments、allocations、bindings、releases、controller、policies、public_ingress、revision、updated_at。Host.host_services 登记主机级入口。public_ingress 登记跨主机公网映射。
66
69
 
67
- 部署状态区分 planned、running、configured、docs_pending、completed、failed、unknown、retired。version 是计划版本;observed_version 只有运行验证成功才更新。完成必须有 `both-sides-verified` 回执,不能只看容器启动或文档标题。
70
+ 部署状态区分 planned、running、configured、docs_pending、completed、failed、unknown、retired。version 是计划版本;observed_version 只有运行验证成功才更新。完成必须有 `both-sides-verified` 回执,不能只看容器启动或文档标题。主机/全域总册必须同时有服务一览表(含主机级入口)和入口规范;缺一不算完整。
68
71
 
69
72
  单主机 I/H 证据在 `hosts/id/runs/run-id/`;D/跨主机证据在 `releases/run-id/`,各主机保存索引。plan.json 与 approval.json 不可覆盖;journal.jsonl 具有摘要链。摘要链能发现内容修改,但不能单凭自身证明尾部没有被有权者完整截断;还应保留执行回执与备份。
70
73
 
71
74
  ## 路径分配
72
75
 
73
- 部署根由 host/project/layout 唯一派生。所有声明的 APP data/config/env/log/backups 路径都必须在该根内;容器只用显式 bind,禁止命名卷、匿名卷、跨项目 bind 和可写根文件系统。项目 env 文件集中在 env/;Compose 使用 raw env_file,要求实际 Compose >=2.30
76
+ 部署根由 host/project/layout 唯一派生。所有声明的 APP data/config/env/log/backups 路径都必须在该根内;容器只用显式 bind,禁止命名卷、匿名卷、跨项目 bind。默认只读容器根;仅当镜像仍必须写根文件系统时,才允许带 `writable_root_justification` 的 `read_only: false`。config/env 默认 0644 只读挂载,供非 root 镜像用户读取。项目 env 文件集中在 env/;Compose 使用 raw env_file,要求实际 Compose >=2.30。`compose --wait` 之后仍检查容器 running 与 Health=healthy;TCP/docker-proxy 监听不是生产健康证明。
74
77
 
75
78
  原生服务设置 HOME、XDG、缓存、临时目录和 OPS_* 到 APP 根内;Linux systemd 还设置 ProtectSystem/ReadWritePaths。通用自定义命令是用户审核的可执行代码,不是一个能阻止恶意程序所有系统调用的沙箱。来源代码必须可信,必须明确映射项目真实数据参数,并实际验证;发现无法约束的数据路径就阻塞,不能报完成。
76
79
 
@@ -65,7 +65,7 @@ node /path/to/ops/common/tools/ops.mjs --state /path/to/.speculo/ops mirror-prob
65
65
 
66
66
  环境配方不抓 latest;管理器缺失先明确准备安装器。来源测速不修改配置,证书/哈希失败候选不使用,真实配置更换通过 H 的精确 write-file/write-control/命令计划。不能将 Python/npm/Docker/Maven 镜像混为一套规则。
67
67
 
68
- H.host_actions 支持 mkdir、write-file(host.root 内相对路径)、write-control(有限系统控制文件)、install-toolchain(明确写集/原默认/验证)、command(明确写集/验证)、defaults、quarantine、purge-quarantine。系统软件包安装使用明确批准的可信安装脚本,不自动猜当前发行版安装命令;Docker 示例见 service-profiles/docker-engine.md
68
+ H.host_actions 支持 mkdir、write-file(host.root 内相对路径;不得写生成器负责的 README/DEPLOYMENTS/knowledge 账本)、write-control(精确系统控制文件:内置 docker daemon.json 与 ops-*.service,以及经理由/回滚/验证声明的 nginx、wireguard、非 ops- 前缀单元)、install-toolchain(明确写集/原默认/验证)、command(明确写集/验证)、defaults、quarantine、purge-quarantine。系统软件包安装使用明确批准的可信安装脚本,不自动猜当前发行版安装命令;Docker 示例见 service-profiles/docker-engine.md。主机级入口用 resource_updates.hosts[].host_services 与 spec.public_ingress 入账,不要为 Nginx/WireGuard 伪造 APP 部署。
69
69
 
70
70
  隔离仅移动登记 cache/log,返回 released_bytes=0。确需释放空间,再为 `_host/quarantine/旧run/精确item` 生成 purge-quarantine 计划。没有回执、内容变化、超出有限清单或试图删除业务数据时阻塞。
71
71
 
@@ -16,7 +16,7 @@ private/credentials.json 是版本化明文账本;credential-put 不会修改
16
16
 
17
17
  控制端项目 README、OPERATIONS 与全域总册保存真实值,特殊字符逐字保留。服务端 README 默认无密码但不能缺路径、版本、时间、启动停止、依赖和备份恢复;OPERATIONS 与 DEPLOYMENTS 默认是受限明文。未知旧密码不能编造;密钥认证没有密码,记录实际密钥认证而不是虚构一个口令。
18
18
 
19
- POSIX 账本/文档/配置副本 0600、控制端目录 0700Windows 使用受限 ACL,不以 chmod 代替 DACL。明文不进入 Git、Web 目录、构建上下文、普通日志;env 是指定的本地配置文件例外,不能再进入镜像层。示例凭据全为演示,不可用于生产。
19
+ POSIX 账本、env 与明文文档 0600、控制端目录 0700。`config/` 与 `*.conf`/`*.acl` 默认 0644,供非 root 容器用户读取只读挂载;Windows 使用受限 ACL,不以 chmod 代替 DACL。明文不进入 Git、Web 目录、构建上下文、普通日志;env 是指定的本地配置文件例外,不能再进入镜像层。示例凭据全为演示,不可用于生产。
20
20
 
21
21
  ## 双边完成门
22
22
 
@@ -73,6 +73,9 @@
73
73
  },
74
74
  "required": [],
75
75
  "additionalProperties": false
76
+ },
77
+ "host_services": {
78
+ "$ref": "#/$defs/host_services"
76
79
  }
77
80
  },
78
81
  "required": [
@@ -84,5 +87,65 @@
84
87
  "identity",
85
88
  "connection"
86
89
  ],
87
- "additionalProperties": false
90
+ "additionalProperties": false,
91
+ "$defs": {
92
+ "host_services": {
93
+ "type": "array",
94
+ "items": {
95
+ "type": "object",
96
+ "properties": {
97
+ "id": {
98
+ "type": "string",
99
+ "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
100
+ "maxLength": 80
101
+ },
102
+ "kind": {
103
+ "enum": [
104
+ "wireguard",
105
+ "nginx",
106
+ "systemd",
107
+ "probe",
108
+ "other"
109
+ ]
110
+ },
111
+ "unit": {
112
+ "type": "string",
113
+ "minLength": 1
114
+ },
115
+ "listen_port": {
116
+ "type": "integer",
117
+ "minimum": 1,
118
+ "maximum": 65535
119
+ },
120
+ "listen": {
121
+ "type": "array",
122
+ "items": {
123
+ "type": "string",
124
+ "minLength": 1
125
+ }
126
+ },
127
+ "tunnel_address": {
128
+ "type": "string",
129
+ "minLength": 1
130
+ },
131
+ "config_path": {
132
+ "type": "string",
133
+ "minLength": 1
134
+ },
135
+ "public_url": {
136
+ "type": "string",
137
+ "minLength": 1
138
+ },
139
+ "notes": {
140
+ "type": "string"
141
+ }
142
+ },
143
+ "required": [
144
+ "id",
145
+ "kind"
146
+ ],
147
+ "additionalProperties": false
148
+ }
149
+ }
150
+ }
88
151
  }