心灵之眼织物

发布: (2025年12月13日 GMT+8 16:26)
6 分钟阅读
原文: Dev.to

Source: Dev.to

第 1 阶段 — C++ 主权内核骨架(守护进程优先)

目标 – 交付一个可运行的 C++ 守护进程,使其能够:

  • 接受事件
  • 维护能力图(端点 + 边)
  • 运行最小状态内核(确定性转换)
  • 写入追加式账本(可追溯 + 可重放)
  • 执行首次“搜索”(基于可达性的图搜索)

非目标(第 1 阶段)

  • 大语言模型集成
  • MindScript 解析/编译
  • 分布式多节点共识
  • 高级持久化引擎(存储将保持简洁 + 可替换)

核心概念

ComponentDescription
ledger / Append‑only log不可变条目,基于文件
state确定性状态机 + 转换规则
graph端点、能力、可达性计算
events进程内发布/订阅总线(守护进程的神经系统)
hunts在约束下搜索可达端点的规划器
daemon主循环 + API 接口(后期支持 HTTP/gRPC;第 1 阶段使用 HTTP)

在第 1 阶段,collapse = 原子提交:

  1. 接收输入(事件 / 命令)
  2. 验证
  3. 计算后果(状态 + 图更新)
  4. 写入一条账本条目(追加式)
  5. 发出内部事件

未经账本提交,不会发生任何变更。


项目结构

mindseye-fabric/
├─ README.md
├─ LICENSE
├─ CMakeLists.txt
├─ docs/
│  └─ 01_phase1_kernel.md
├─ src/
│  ├─ main.cpp
│  ├─ daemon/
│  │  ├─ server.hpp
│  │  ├─ server.cpp
│  │  ├─ routes.hpp
│  │  └─ routes.cpp
│  ├─ core/
│  │  ├─ types.hpp
│  │  ├─ time.hpp
│  │  └─ result.hpp
│  ├─ ledger/
│  │  ├─ ledger.hpp
│  │  ├─ ledger.cpp
│  │  └─ entry.hpp
│  ├─ state/
│  │  ├─ state.hpp
│  │  ├─ state.cpp
│  │  └─ transitions.hpp
│  ├─ graph/
│  │  ├─ graph.hpp
│  │  ├─ graph.cpp
│  │  ├─ endpoint.hpp
│  │  └─ capability.hpp
│  ├─ events/
│  │  ├─ bus.hpp
│  │  └─ bus.cpp
│  └─ hunts/
│     ├─ hunt.hpp
│     └─ hunt.cpp
├─ third_party/
│  └─ httplib.h
└─ tests/
   └─ test_smoke.cpp

每个文件夹都是内核的“器官”;不存在混合用途的“utils”目录。


CMake 配置

cmake_minimum_required(VERSION 3.20)
project(mindseye_fabric LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(mindseye_fabric
  src/main.cpp
  src/daemon/server.cpp
  src/daemon/routes.cpp
  src/events/bus.cpp
  src/ledger/ledger.cpp
  src/state/state.cpp
  src/graph/graph.cpp
  src/hunts/hunt.cpp
)

target_include_directories(mindseye_fabric PRIVATE
  src
  third_party
)

# Good defaults
if(MSVC)
  target_compile_options(mindseye_fabric PRIVATE /W4)
else()
  target_compile_options(mindseye_fabric PRIVATE -Wall -Wextra -Wpedantic)
endif()

核心类型 (src/core/types.hpp)

#pragma once
#include 
#include 
#include 
#include 
#include 
#include 
#include 

namespace me {

using u64 = std::uint64_t;
using i64 = std::int64_t;

struct Error {
  std::string code;
  std::string message;
};

template 
using Result = std::variant;

inline bool ok(const auto& r) {
  return std::holds_alternative(r))>>(r);
}

} // namespace me

核心时间 (src/core/time.hpp)

#pragma once
#include 
#include "core/types.hpp"

namespace me {

inline u64 now_ms() {
  using namespace std::chrono;
  return static_cast(duration_cast(system_clock::now().time_since_epoch()).count());
}

} // namespace me

账本条目格式

每条条目是一行 JSON(NDJSON),便于实时查看和重放。

FieldDescription
id单调递增整数
ts_ms时间戳(毫秒)
kind"event"
payloadJSON 对象(第 1 阶段序列化为字符串)
prev_hash前一条目的哈希
hash当前条目的哈希(完整性链)

src/ledger/entry.hpp

#pragma once
#include 
#include "core/types.hpp"

namespace me {

struct LedgerEntry {
  u64 id = 0;
  u64 ts_ms = 0;
  std::string kind;
  std::string payload_json;
  std::string prev_hash;
  std::string hash;
};

} // namespace me

账本实现 (src/ledger/ledger.hpp / .cpp)

头文件

#pragma once
#include 
#include 
#include 
#include "ledger/entry.hpp"
#include "core/types.hpp"

namespace me {

class Ledger {
public:
  explicit Ledger(std::string path);

  Result append(std::string kind, std::string payload_json);

  std::optional last() const;
  u64 next_id() const;

private:
  std::string path_;
  mutable std::mutex mu_;
  u64 next_id_{1};
  std::optional last_;

  static std::string sha256_hex(std::string_view data); // stub for Phase 1
  static std::string compute_hash(const LedgerEntry& e);
};

} // namespace me

实现

#include "ledger/ledger.hpp"
#include "core/time.hpp"
#include 

namespace me {

static std::string fake_hash(std::string_view s) {
  // Phase 1 placeholder – replace with real SHA‑256 later.
  std::hash h;
  return std::to_string(h(s));
}

Ledger::Ledger(std::string path) : path_(std::move(path)) {
  // Start fresh if the file does not exist.
  std::ifstream in(path_);
  if (!in.good()) return;

  // Minimal restore: read the last line only (fast path).
  std::string line, last_line;
  while (std::getline(in, line))
    if (!line.empty()) last_line = line;

  // Phase 1: keep next_id_ conservative.
  if (!last_line.empty()) next_id_ = 1000; // placeholder
}

std::optional Ledger::last() const {
  std::scoped_lock lk(mu_);
  return last_;
}

u64 Ledger::next_id() const {
  std::scoped_lock lk(mu_);
  return next_id_;
}

std::string Ledger::sha256_hex(std::string_view data) {
  return fake_hash(data);
}

std::string Ledger::compute_hash(const LedgerEntry& e) {
  std::ostringstream ss;
  ss  Ledger::append(std::string kind, std::string payload_json) {
  std::scoped_lock lk(mu_);
  LedgerEntry e;
  e.id = next_id_++;
  e.ts_ms = now_ms();
  e.kind = std::move(kind);
  e.payload_json = std::move(payload_json);
  e.prev_hash = last_ ? last_->hash : "GENESIS";
  e.hash = compute_hash(e);

  std::ofstream out(path_, std::ios::app);
  if (!out.good())
    return Error{"LEDGER_IO", "Failed to open ledger file for append"};

  // NDJSON line
  out 

状态头文件 (src/state/state.hpp)

#include "core/types.hpp"

namespace me {

enum class State : u64 {
  PAUSE = 0,
  STRESS = 1,
  LOOP = 2,
  TRANSMIT = 3,
  COLLAPSE = 4
};

inline std::string to_string(State s) {
  switch (s) {
    case State::PAUSE:    return "PAUSE";
    case State::STRESS:   return "STRESS";
    case State::LOOP:     return "LOOP";
    case State::TRANSMIT: return "TRANSMIT";
    case State::COLLAPSE: return "COLLAPSE";
  }
  return "UNKNOWN";
}

struct Transition {
  State from;
  State to;
  std::string reason;
};

class StateKernel {
public:
  State current() const { return current_; }

  // Phase 1: simple rule set. Later: constraints + costs + guards.
  Transition apply_event(std::string_view event_type);

private:
  State current_{State::PAUSE};
};

} // namespace me

实现 (src/state/state.cpp)

#include "state/state.hpp"

namespace me {

Transition StateKernel::apply_event(std::string_view event_type) {
  // Deterministic, minimal mapping for Phase 1.
  if (event_type == "ingest") {
    State prev = current_;
    current_ = State::LOOP;
    return {prev, current_, "ingest -> LOOP"};
  }
  if (event_type == "pressure") {
    State prev = current_;
    current_ = State::STRESS;
    return {prev, current_, "pressure -> STRESS"};
  }
  // Default:
Back to Blog

相关文章

阅读更多 »