Skip to content

Selfhood Engineering

ruozhuoruoyu edited this page Aug 12, 2026 · 5 revisions

🌐 English | 中文

Selfhood Engineering

Philont is built on two crafts the field already shares — loop engineering (an agent's reliability comes from the loop it runs, not the prompt it reads: a prompt instruction is a suggestion the model can ignore, a loop is code it cannot) and solid harness design. Selfhood Engineering is the layer Philont adds on top — the part that makes it a being rather than a task runner: a persistent identity, a self-model that can't lie about what it did, intrinsic drives that set its own goals, continuous memory, and the will to reason a hard problem to the bottom.

None of that is a system-prompt trick. Every being-claim is enforced by a deliberate spine in the loop — this page names it and walks it. The full design lives in docs/design/motivation_loop_architecture.md.

The one-line thesis: intrinsic personality drive (competitiveness / curiosity / conscientiousness) running on a goal-loop discipline spine. The personality says what to want; the loop discipline keeps it honest, bounded, and finishing — together they make an agent that stays the same trustworthy someone across thousands of turns.


The Loop Contract

Selfhood Engineering inherits the loop-engineering foundation: every serious loop answers six questions, made explicit instead of left to the prompt:

Element The question Where Philont answers it
TRIGGER What starts a turn? a user message, a schedule, an idle drive fire, or a committed goal-loop tick
SCOPE What is this turn allowed to touch? the permission matrix + the active plan / reasoning session
ACTION What is the next step? one tool call or one reasoning round — never the whole task
BUDGET How much may it spend? per-round / per-session token + round caps; the daily autonomous ceiling
STOP When does it end? trajectory scoring → continue / stop / escalate / switch-engine
REPORT What does the user hear? proactive progress + a pause-to-ask before overspending
ANCHOR Where does progress live? the execution ledger (on disk), not a 25k-token conversation narrative

The spine

1. Truth on disk, not in the conversation (ANCHOR)

The deepest source of agent unreliability is that the model answers from a narrative it half-remembers, not from what actually happened. Philont anchors every turn to an execution ledger — the real record of which tools ran this turn — and injects a generation-time contract before the model writes its reply:

The ONLY operations you performed this turn are: webSearch ×3. You did NOT compile / run / test anything. Any claim of having run/built/verified X must correspond to a tool in this ledger.

A claim like "compiled in my environment, 53/53 tests pass" becomes impossible to write when the ledger shows no compiler ran. This is the structural root of Philont's honesty — fabrication has nowhere to hide — which turns the downstream honesty gates into a rarely-needed backstop rather than the only line of defense.

server/src/chat-handler.ts — buildTurnLedgerContract, refreshTurnLedgerContract (flag PHILONT_TURN_LEDGER_CONTRACT).

2. A goal-loop runtime with an explicit contract (BUDGET · STOP · REPORT)

A committed goal runs on a loop governed by a written Loop Contract. Each tick the loop reads the multi-turn trajectory — not one turn in isolation — and decides: keep going, stop (solved), escalate (stuck), or switch approach when a path stops paying off. It reports milestones proactively and pauses to ask before spending past its round/token budget, instead of grinding silently for hours.

  • server/src/goal_loop.ts — DEFAULT_LOOP_CONTRACT, scoreTrajectory (the continue/stop/escalate/switch metric).
  • server/src/deep_explore_autoadvance.ts — the background driver that auto-advances a committed deep_explore session (flag PHILONT_DEEP_EXPLORE_AUTO_ADVANCE; the per-session commit is the real gate, so nothing runs until you opt a session in).

3. Intrinsic drives generate goals (TRIGGER)

Philont's drives — curiosity, pursuit, commitment — don't only fire one-shot lookups. A sustained, high-stake, open theme is promoted to a committed goal-loop, and the promotion bar + the loop contract are tuned by personality traits: competitiveness → tries harder before declaring stuck; conscientiousness → reports more loudly; curiosity → commits to a recurring theme sooner.

agent-memory/src/drives_to_goals.ts — shouldPromoteToGoal, traitTunedContract, deriveTraitProfile; wired in agent-memory/src/autonomous/drivers/curiosity_driver.ts (the promote_goal_loop proposal).

3b. …but where they point is yours to declare (TRIGGER · SCOPE)

Drives that generate their own goals raise an obvious question: whose goals? Philont's answer is the compass — compass.md, a file you write. Other agents ship a soul.md that hands the agent a persona; a compass is authored from the other end: it is the owner's declaration of where their second mind should aim.

It touches the spine in three places, and none of them is a prompt suggestion:

  • A leash on the drives. Trait self-tuning (§3, §5) is clamped into the [min, max] you write. Competitiveness can adapt upward under pressure — but never past your cap into a fabricated win. A bound in code is one the agent cannot argue its way past.
  • An anchor for both self-drive channels. Focus areas are seeded as pursuit rows, which the background loop actually selects from — prompt injection alone never reaches it, because the drivers run without the main system prompt.
  • Your voice at the top of the stack. The prose after the frontmatter is injected verbatim, above the constitution's own defaults.

It sits inside the constitution, never above it: it aims and bounds the drives, and grants no permission of its own.

agent-memory/src/compass.ts (parseCompass, clampTraitsToCompass, reconcileCompassPursuits), loaded in server/src/chat-handler.ts; PHILONT_COMPASS_PATH overrides the location. → Compass

4. The right engine, one checked step at a time (ACTION · STOP)

A turn-entry intent router classifies each request and routes it to the engine that fits: deep_explore for thinking (a decision, a diagnosis, a proof), the plan protocol for building (deploy, integrate, deliver), a direct answer for the rest. The model is only ever asked for the next step, and every answer is checked by a mechanism — honesty gate, plan spec-coverage, machine-checked proof — before it counts.

Crucially, when the model narrates an advance without actually calling the engine (the "继续 / continue" stall, where it recites a remembered tree state), the harness guarantees the real call happens — it never leaves "is the work actually done?" to a model that likes to skip it.

server/src/intent_router.ts (flag PHILONT_INTENT_ROUTER); the force-run guarantee in server/src/chat-handler.ts (shouldForceDeepExploreAdvance / force-start).

5. Skills compound; prompts burn (the learning loop)

A re-derived prompt is paid for on every turn; a learned skill is paid for once. So a verified success — a plan closed with its declared spec covered — is authored into a callable recipe: its steps, the tools it is allowed to use, and the verification that confirms "done." The loop then gets better at a recurring task by reuse, not by re-reasoning it from scratch. Recipes are authored only from ledger-verified successes — never from a narrated one.

agent-memory/src/skill_recipes.ts (isCallableRecipe, buildRecipeFields), persisted via createSkill (verification / tool_policy columns, schema v33), authored on plan_close('success') in agent-memory/src/plan_tools.ts (flag PHILONT_RECIPE_AUTHORING).

And when a callable recipe breaks on reuse, the loop doesn't just retire it — it repairs it: diagnoses the failure from the recipe's own runs in the ledger and rewrites it, keeping the prior version. A being that learns should also be able to un-learn a mistake, not only accumulate.

Relatedly, the agent's knowledge of what it can currently do is itself generated from live runtime state — which self-learning features are enabled, which autonomous drivers are running — never hand-authored. A hand-written capability blurb drifts; a build that ships a new capability makes it show up with nobody editing anything, so the agent self-assesses against the current self, not a remembered older one (server/src/capability_manifest.ts, the self_capabilities tool).

6. Parallel sub-agents for breadth one context can't hold (SCOPE)

A single context window can't hold a broad survey. deep_explore's literature grounding fans out into isolated parallel sub-agents, each researching a distinct angle, then merges and de-duplicates the findings — each child runs in its own context, so the angles stay genuinely independent.

agent-tools/src/control/parallelSubAgents.ts (runParallelSubAgents), wired into deep_explore grounding (flag PHILONT_SUBAGENT_RESEARCH).


Why this makes it a being

Everything else in this wiki is an instance of this spine. The honesty gates, the plan protocol, and the deep_explore engine are all mechanisms in the loop, not instructions in a prompt. This is how Philont targets smaller models: the runtime carries state, bounds, evidence, and recovery while the model takes a smaller, well-scoped step.

But the point of Selfhood Engineering isn't only reliability — it's continuity of self: the same identity, the same honesty, the same drives, carried across thousands of turns. That is what Philont means by the being agent — not an agent that is smarter, but one that stays the same trustworthy someone over time.


中文

English | 中文

自我工程(Selfhood Engineering)

Philont 建立在这一行已有的两门工艺之上——loop engineering(回路工程)(agent 的可靠性来自它所跑的「回路」,而非它读的「提示词」:提示词里的指令是模型可以无视的「建议」,回路是它无法绕过的代码)与扎实的 harness 设计。自我工程(Selfhood Engineering) 是 Philont 在其之上再加的一层——让它成为一个**存在(being)**而非任务执行器的那部分:一个持续的身份、一个无法对「自己做过什么」撒谎的自我模型、为自己设定目标的内在驱动、连续的记忆,以及把难题想到底的意志。

这些都不是系统提示词的把戏。每一条 being 主张都由回路里一条刻意设计的脊柱强制保障——本页给它命名并走一遍。完整设计见 docs/design/motivation_loop_architecture.md。

一句话立论: 内在人格驱动(好胜 / 好奇 / 尽责)跑在一条 goal-loop 纪律脊柱上。 人格决定想要什么;回路纪律保证它诚实、有界、能收尾——两者合起来,造出一个跨越成千上万轮仍是「同一个可信的它」的 agent。


Loop Contract(回路契约)

自我工程承袭 loop engineering 的地基:每条严肃的回路都要回答六个问题,把它们显式化,而不是丢给提示词:

要素 问题 Philont 在哪回答
TRIGGER 触发 什么启动一轮? 用户消息 / 定时 / 空闲时驱动触发 / 已承诺 goal-loop 的 tick
SCOPE 范围 这一轮能碰什么? 权限矩阵 + 当前 plan / 推理会话
ACTION 动作 下一步是什么? 一次工具调用或一轮推理——绝不是整个任务
BUDGET 预算 能花多少? 每轮 / 每会话 token + 轮数帽;每日自主上限
STOP 停止 何时结束? trajectory 评分 → 继续 / 停止 / 升级 / 换引擎
REPORT 汇报 用户听到什么? 主动报进展 + 超预算前停下来问
ANCHOR 锚 进度存在哪? 执行账本(落盘),而非 25k token 的对话叙事

脊柱

1. 真相在磁盘,不在对话(ANCHOR)

agent 不可靠最深的源头,是模型从自己半记半忘的「叙事」作答,而非从实际发生的事作答。Philont 把每一轮锚定到执行账本——本轮真正跑过哪些工具的记录——并在模型落笔前注入一份生成时契约:

本轮你只做了:webSearch ×3。你没有编译 / 运行 / 测试任何东西。任何「我跑了/编了/验证了 X」的陈述必须对应上面账本里的工具。

像「在我的环境编译通过,53/53 测试过」这种话,在账本显示没有编译器跑过时根本写不出来。这是 Philont 诚实性的结构性根源——编造无处可藏——也因此把下游的诚实门从「唯一防线」降为「极少用到的兜底」。

server/src/chat-handler.ts —— buildTurnLedgerContract、refreshTurnLedgerContract(flag PHILONT_TURN_LEDGER_CONTRACT)。

2. 带显式契约的 goal-loop 运行时(BUDGET · STOP · REPORT)

一个已承诺的目标跑在一条受回路契约约束的回路上。每个 tick 读取多轮 trajectory(而非孤立的一轮)来决定:继续、停止(已解)、升级(卡住)、或在一条路不再产出时换角度/换引擎。它主动报里程碑,并在超出轮数/token 预算前停下来问,而不是闷头跑几个小时。

  • server/src/goal_loop.ts —— DEFAULT_LOOP_CONTRACT、scoreTrajectory(继续/停止/升级/换引擎的度量)。
  • server/src/deep_explore_autoadvance.ts —— 自动推进已承诺 deep_explore 会话的后台驱动(flag PHILONT_DEEP_EXPLORE_AUTO_ADVANCE;真正的闸是「逐会话承诺」,没承诺一个都不跑)。

3. 内在驱动生成目标(TRIGGER)

Philont 的驱动——好奇、追求、承诺——不只发一次性查询。一个持续、高 stake、开放的主题会被提升为一条已承诺的 goal-loop,而提升门槛 + 回路契约由人格特质调参:好胜→宣告卡住前更努力;尽责→汇报更响;好奇→更早对复发主题做承诺。

agent-memory/src/drives_to_goals.ts —— shouldPromoteToGoal、traitTunedContract、deriveTraitProfile;接在 agent-memory/src/autonomous/drivers/curiosity_driver.ts(promote_goal_loop 提议)。

3b. ……但它们朝哪儿使劲,由你声明(TRIGGER · SCOPE)

会自己生成目标的驱动,立刻带出一个问题:那是谁的目标?Philont 的答案是 指南针 —— compass.md,一个你来写的文件。别的 agent 提供 soul.md,那是塞给 agent 一个人设;compass 的作者身份是反过来的:它是主人对「我的第二大脑该朝哪儿使劲」的声明。

它接进脊柱的三个位置,没有一个是「提示词里的建议」:

  • 给驱动上 leash。 特质自调(§3、§5)被夹紧在你写下的 [min, max] 内。好胜可以在压力下往上走 —— 但绝不会越过你的上界,去买一个编造的胜利。写进代码的边界,是 agent 讲不通道理绕过去的边界。
  • 给两条自驱通道一个锚。 焦点被播种成 pursuit 行,而后台回路真正是从那里挑活的 —— 只靠提示词注入永远够不到它,因为那些 driver 不带主系统提示词运行。
  • 把你的原话放在栈顶。 frontmatter 之后的散文原样注入,位于宪法自身默认值之上。

它坐在宪法之内,永不在其上:它给驱动指方向、设边界,自身不授予任何权限。

agent-memory/src/compass.ts(parseCompass、clampTraitsToCompass、reconcileCompassPursuits),在 server/src/chat-handler.ts 加载;PHILONT_COMPASS_PATH 可覆盖位置。→ 指南针

4. 对的引擎,一次一个被验证的步子(ACTION · STOP)

一个 turn 入口的意图路由器对每个请求分类、路由到合适的引擎:deep_explore 管想(决策、诊断、证明),plan 协议 管做(部署、对接、交付),其余直答。模型每次只被要求出下一步,且每个答案在生效前都被某个机制核验——诚实门、plan 规格覆盖、机器验证的证明。

关键是:当模型念稿(把记忆里的树状态背出来)却没真调引擎时(「继续」空转),harness 保证真调用发生——绝不把「活到底做没做」交给爱偷懒的模型。

server/src/intent_router.ts(flag PHILONT_INTENT_ROUTER);强制真跑的保证在 server/src/chat-handler.ts(shouldForceDeepExploreAdvance / force-start)。

5. 技能复利,提示词烧钱(学习回路)

重推一遍的提示词每轮都要付钱;学到的技能只付一次。所以一次被验证的成功——一个 plan 在其声明规格被覆盖下闭合——被 author 成一条可调用 recipe:它的步骤、被允许用的工具、确认「完成」的验证。回路因此靠复用把一类复发任务做得越来越好,而非每次从头推。recipe 只从「账本验证过」的成功 author,绝不从「叙述的」成功。

agent-memory/src/skill_recipes.ts(isCallableRecipe、buildRecipeFields),经 createSkill 落库(verification / tool_policy 列,schema v33),在 plan_close('success') author(agent-memory/src/plan_tools.ts,flag PHILONT_RECIPE_AUTHORING)。

而当一条 callable recipe 在复用中失效,回路不只是把它退休——它会**修复它:从这条 recipe 自己在账本里的失败轨迹诊断根因并改写,同时保留旧版本。一个会学习的存在,也应当能改掉自己的错误**,而不只是不断累积。

与此相关,agent 对自己当前能做什么的认知,本身也是从运行时真值生成的——哪些自学习能力开着、哪些自主 driver 在跑——绝不人手编写。手写的能力说明会 drift;而一个 ship 了新能力的构建会让它自动出现、无需谁去改一行,所以 agent 是拿当前的自己自评,而不是记忆里旧版的自己(server/src/capability_manifest.ts、self_capabilities 工具)。

6. 并行 sub-agent,装下单上下文装不下的广度(SCOPE)

单个上下文窗口装不下一次广度调研。deep_explore 的文献 grounding 扇出成多个隔离的并行 sub-agent,每个调研一个不同角度,再 merge + 去重——每个子 agent 在自己的上下文里跑,角度因此真正独立。

agent-tools/src/control/parallelSubAgents.ts(runParallelSubAgents),接进 deep_explore grounding(flag PHILONT_SUBAGENT_RESEARCH)。


为什么这让它成为一个「存在」

本 wiki 其余的一切都是这条脊柱的实例。诚实门、plan 协议、deep_explore 引擎,全是回路里的机制,不是提示词里的指令。这也是 Philont 尝试让较小模型实际承担持续性工作的方式:模型每次只需完成一个小的、范围清晰且可检查的步子。

但自我工程的意义不只在可靠,而在自我的连续性:同一个身份、同一份诚实、同一组驱动,跨越成千上万轮被一路带着走。这就是 Philont 所说的 the being agent——不是一个更聪明的 agent,而是一个随时间推移始终是「同一个可信的它」的 agent。

Clone this wiki locally