<feed xmlns='http://www.w3.org/2005/Atom'>
<title>living-village.git/src/LivingVillage.Kernel, branch main</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.
</subtitle>
<id>http://git.somhairle.bid/living-village.git/atom?h=main</id>
<link rel='self' href='http://git.somhairle.bid/living-village.git/atom?h=main'/>
<link rel='alternate' type='text/html' href='http://git.somhairle.bid/living-village.git/'/>
<updated>2026-09-29T00:09:12+00:00</updated>
<entry>
<title>p66: 每日任务目标具体化 TargetNpc/TargetTile 定点</title>
<updated>2026-09-29T00:09:12+00:00</updated>
<author>
<name>Somhairle H. Marisol</name>
<email>muqiu-han@outlook.com</email>
</author>
<published>2026-09-29T00:09:12+00:00</published>
<link rel='alternate' type='text/html' href='http://git.somhairle.bid/living-village.git/commit/?id=247d0bc083dffc648f043176eabf9bd4036f19e7'/>
<id>urn:sha1:247d0bc083dffc648f043176eabf9bd4036f19e7</id>
<content type='text'>
- Kernel Occupation：TaskTargets + targetNpcOf/targetTileOf + dailyTaskOfWith/
  refreshTodayWith/refreshStateWith（splitmix 同源定点，候选排序消除顺序依赖，禁随机）
- 仅既有 satisfiesCompletion 会读目标的模板定点：帮工→TargetNpc、翻土→TargetTile；
  其余 8 模板目标保持 None（不改完成语义）
- Desktop WorldBootstrap：reachableTargets（世界 NPC + 样板菜地瓦片）+
  occupationStateForWorld/refreshOccupationTodayWorld；Game 开局/跨日/证据路径切换
- 历史入口 dailyTaskOf/refreshState/occupationStateFor 保留为空候选通配包装（逐字节不变）
- 红先 P66TaskTargetTests（8 例）：同 seed 幂等、跨 seed 落在可达集合、候选顺序无关、
  历史通配回归、帮工/翻土定点门控完成、跨日重定点、v3 round-trip + v2 基线
- scripts/p66-target-report.fsx + docs/evidence/p66-analysis.txt（PASS）
- Desktop 328/328，Kernel 119/119；digest 953775FA…7F6C ×3 PASS；Sim.fs 未动
</content>
</entry>
<entry>
<title>p65: 职业切片五 货郎打听行情读 World.Rumors（中文行情短答 + 稿证据）</title>
<updated>2026-09-28T22:51:21+00:00</updated>
<author>
<name>Somhairle H. Marisol</name>
<email>muqiu-han@outlook.com</email>
</author>
<published>2026-09-28T22:51:21+00:00</published>
<link rel='alternate' type='text/html' href='http://git.somhairle.bid/living-village.git/commit/?id=2da1cbaf253245c437800e80b9aed9e8e47306b5'/>
<id>urn:sha1:2da1cbaf253245c437800e80b9aed9e8e47306b5</id>
<content type='text'>
- Kernel Occupation 新增 freshReliableRumors/inquiryRumor/marketInquiryText（纯判定+文案，
  对齐 Sim.latestRumorFor 新鲜度/可信度口径，全序命中规则，禁随机；不改 Sim.fs）
- Desktop chooseIntent：货郎 OfferTrade 读对话前谣言池，Status=inquiry|&lt;短答&gt;；statusLabel 透出
- 真字补 17 字（东头西北巷口盐巴米布茶柴涨两文落些）并重出 atlas（340 字/384x528）
- 红先 P65RumorInquiryTests（6 例）：命中/幂等/陈旧·微弱·空池/仅货郎/非货郎回归逐字节/
  save v2 头不变+v3 round-trip/穷举组合无缺字
- LV_P65_SHOT 钩子 + scripts/analyze-p65.py + docs/evidence/p65-*（PASS）
- Desktop 320/320，Kernel 119/119；digest 953775FA…7F6C ×3 PASS
</content>
</entry>
<entry>
<title>p55: 当日任务经济闭环——设计口径物品报酬入账(夜捕鱼×2/送粮食物×1, 其余不发) + 连续完成天数(streak 跨日保留/漏完成清零) + v3 streak 尾段与 save(None) 兼容 + LV_P55_SHOT 证据</title>
<updated>2026-09-28T16:24:08+00:00</updated>
<author>
<name>Somhairle H. Marisol</name>
<email>muqiu-han@outlook.com</email>
</author>
<published>2026-09-28T16:24:08+00:00</published>
<link rel='alternate' type='text/html' href='http://git.somhairle.bid/living-village.git/commit/?id=a59a4bbe1ab45adb29d1367995230d3f09847d9b'/>
<id>urn:sha1:a59a4bbe1ab45adb29d1367995230d3f09847d9b</id>
<content type='text'>
</content>
</entry>
<entry>
<title>p51: 职业系统实现首切片——开局钱/体力/背包侧车 + 当日任务/跨日刷新 + StartNewGameWith 读回(design §2.4-1)</title>
<updated>2026-09-28T14:38:52+00:00</updated>
<author>
<name>Somhairle H. Marisol</name>
<email>muqiu-han@outlook.com</email>
</author>
<published>2026-09-28T14:38:52+00:00</published>
<link rel='alternate' type='text/html' href='http://git.somhairle.bid/living-village.git/commit/?id=aa3baa953ea5c4f99f5f23cb3eef9400338b61ec'/>
<id>urn:sha1:aa3baa953ea5c4f99f5f23cb3eef9400338b61ec</id>
<content type='text'>
</content>
</entry>
<entry>
<title>feat(kernel,desktop): P31 step3 story annals + identity entry + glyph atlas</title>
<updated>2026-09-22T08:33:03+00:00</updated>
<author>
<name>Somhairle H. Marisol</name>
<email>muqiu-han@outlook.com</email>
</author>
<published>2026-09-22T08:33:03+00:00</published>
<link rel='alternate' type='text/html' href='http://git.somhairle.bid/living-village.git/commit/?id=9821b54ff2a77539898b62471d79dc4685b59cad'/>
<id>urn:sha1:9821b54ff2a77539898b62471d79dc4685b59cad</id>
<content type='text'>
- Sim.AnnalKind gains StoryAnnal (summary lives in the existing Summary
  field); WorldSave v3 serializes it with the new 'story' token. v1/v2
  saves never contain the token and stay byte-identical; v3 save -&gt; load
  -&gt; save roundtrips byte-for-byte (tested).
- Occupation.Story.identitySummaryOf: plain chronicle-style identity line
  written to the yearbook at game start (design section 3), e.g. yi-da-yu-wei-sheng.
- Desktop: story summaries render in the chronicle panel; StartNewGame
  appends the identity annal; chooseIntent now routes responses through
  Occupation.biasResponse and advances the storyline (one stage per
  player dialogue) with the summary appended as a StoryAnnal.
- M5View gains Seed (world seed source for the story start-day hash).
- Chinese copy synced into requiredUiLabels; cjk-glyphs.txt +
  CjkGlyphAtlas.characterTable extended 238 -&gt; 307 glyphs (384x480),
  atlas regenerated with the deterministic script.
- 4 new kernel tests (115 -&gt; 119); performance digest unchanged.
</content>
</entry>
<entry>
<title>feat(kernel): P31 step2 story stage state machine</title>
<updated>2026-09-22T08:24:19+00:00</updated>
<author>
<name>Somhairle H. Marisol</name>
<email>muqiu-han@outlook.com</email>
</author>
<published>2026-09-22T08:24:19+00:00</published>
<link rel='alternate' type='text/html' href='http://git.somhairle.bid/living-village.git/commit/?id=0539bba17c260f6a4b51d3cefddac0ff448c19bc'/>
<id>urn:sha1:0539bba17c260f6a4b51d3cefddac0ff448c19bc</id>
<content type='text'>
- Occupation.Story: three-segment arc per occupation (accept task -&gt; visit
  households -&gt; conclude), driven one stage per player dialogue with day
  gates derived from the same splitmix pattern as the daily task pool
  (start day = hash(seed ^ storySeed, day 0) mod 3 + 2, range [2,4]).
- relationMeanToPlayer: decayed valence mean over acquainted NPCs only
  (same decay formula as Sim.relationMatrix); no acquaintances = 0.
- Three endings (warm/plain/distant) chosen by deterministic thresholds
  (&gt;=0.3 / &gt;=0.0 / &lt;0); ending text is fixed at the concluding dialogue.
- onDialogue returns (state, summary text option) for the caller to write
  into the yearbook; StoryStage itself is unchanged (0..3) and already
  roundtrips through the existing v3 occupation segment.
- 14 new kernel tests (101 -&gt; 115); performance digest unchanged.
</content>
</entry>
<entry>
<title>feat(kernel): P31 step1 occupation dialogue response bias</title>
<updated>2026-09-22T08:16:40+00:00</updated>
<author>
<name>Somhairle H. Marisol</name>
<email>muqiu-han@outlook.com</email>
</author>
<published>2026-09-22T08:16:40+00:00</published>
<link rel='alternate' type='text/html' href='http://git.somhairle.bid/living-village.git/commit/?id=6c2f180cc7c8315e32d88cbe5d44928d495fe473'/>
<id>urn:sha1:6c2f180cc7c8315e32d88cbe5d44928d495fe473</id>
<content type='text'>
- Occupation.biasResponse: deterministic pure remap over Sim.responseFor;
  no occupation = byte-identical pass-through (all intents x personalities).
  farmer AskHelp Refused-&gt;Helpful; fisher SmallTalk Reserved-&gt;Friendly;
  peddler SmallTalk Reserved-&gt;Bargaining; scholar Joke fully overridden to
  Reserved (documented total-override semantics, opposite of personality).
- Sim.responseFor made public (same pure function, reused as the base path).
- Sim.chooseDialogueWith: extracted body of chooseDialogue with an injectable
  respond function; chooseDialogue keeps identity semantics unchanged.
- Sim.appendAnnal made public for the upcoming story annal writes.
- 9 new kernel tests (92 -&gt; 101); performance digest unchanged.
</content>
</entry>
<entry>
<title>perf(kernel): P27 第二步 — Rumor 扫描去装箱 + 裁剪判定 O(1)</title>
<updated>2026-09-22T02:46:16+00:00</updated>
<author>
<name>Somhairle H. Marisol</name>
<email>muqiu-han@outlook.com</email>
</author>
<published>2026-09-22T02:46:16+00:00</published>
<link rel='alternate' type='text/html' href='http://git.somhairle.bid/living-village.git/commit/?id=a0597455629618a282b582d13c23bfeab786e7d2'/>
<id>urn:sha1:a0597455629618a282b582d13c23bfeab786e7d2</id>
<content type='text'>
两条互相独立、均不改变保留集合与查询结果的优化：

1) 扫描去装箱：latestRumorFor / rumorIsDuplicate 用 `=` 比较 [&lt;Struct&gt;] 的
   NpcId/RumorId（含 RumorId option）会走泛型结构相等并逐条装箱（实测 ~24 B/条，
   Sim.chat 单独测得 N=16000 时 393,736 B/次、随 N 线性）。改为先解构底层
   int/int64 再比较；Parent 用 int64 option 比较替代 RumorId option 结构相等。
   语义完全等价，扫描不再逐条分配。

2) 裁剪判定 O(1)：World 新增派生镜像 RumorCount/RumorOldestDay（不参与存档，
   读档由列表经 rumorWorkingSetStats 重建）。appendRumor 用「count+1&gt;capacity
   或 min(oldest,day)&lt;cutoff」O(1) 判定，仅真需裁剪时才走 trimRumors；旧 consRumor
   每次追加都 rumorsNeedTrim 全表扫一遍。条件与 needTrim 逐字等价，保留集合相同。

等价性验证：5 天 2000 聊天/天跑两遍 WorldSave.save 逐字节相同，
RumorCount/RumorOldestDay 与对列表重算一致（count=8000、oldest_day=1）。

Kernel 长跑基准 30 NPC × 2000 聊天/天（--rumor-bench D 30 2000）：
 days  修复前 alloc / ms        修复后 alloc / ms
  3    930,716,456 / 1626.7     482,716,192 / 1511.3
 30  13,419,045,864 / 12182.5  4,884,067,640 / 8879.6
 60  27,297,668,608 / 23769.7  9,774,660,360 / 17078.2
60 天分配 -64%、耗时 -28%，retained_id_checksum=927964000 前后一致。

门槛：final_digest=953775FAEB2F... 三次一致、performance_determinism=PASS；
Kernel 92 / Desktop 143 全绿；--cost-probe 1/5 天 18.7s/18.8GB、90.4s/94.6GB
（全模拟分配由逐 tick NPC 快照主导，谣言子系统占比很小，故全模拟基本持平）。
</content>
</entry>
<entry>
<title>perf(kernel): P27 第一步 — Rumor 长跑基准与修复前量化</title>
<updated>2026-09-22T02:36:39+00:00</updated>
<author>
<name>Somhairle H. Marisol</name>
<email>muqiu-han@outlook.com</email>
</author>
<published>2026-09-22T02:36:39+00:00</published>
<link rel='alternate' type='text/html' href='http://git.somhairle.bid/living-village.git/commit/?id=164f4749460a304c1aaad4900ef3facc29859eb0'/>
<id>urn:sha1:164f4749460a304c1aaad4900ef3facc29859eb0</id>
<content type='text'>
新增 Kernel 层 Rumor 长跑基准（RumorBench.fs + headless --rumor-bench
[days npcs chats_per_day]），把「聊天→生成/追溯谣言」路径从 Sim.step 的 NPC
快照分配解耦，隔离测量谣言工作集随世界年龄的分配/耗时；同 Config 的
retained_id_checksum 证明确定性。

复核 M3-1 前提：World.Rumors 已被 M6a（d94ec2d/cc850bf）按 3 天保留窗口收敛，
单日成本平稳（1/5/10 天 ≈18.7/18.1/19.8s、≈19GB/天），超线性项消失。
剩余 Rumor 成本 = 每次聊天的两条 O(N) 扫描 latestRumorFor/rumorIsDuplicate，
且 [&lt;Struct&gt;] NpcId/RumorId 用 = 比较会逐条装箱（Sim.chat 单独测得 N=16000
时 393,736 B/次、随 N 线性）。

修复前基准（30 NPC，--rumor-bench D 30 2000）：
 3d  chat_calls=6000   retained=6000  alloc=930,716,456   ms=1626.7
 30d chat_calls=60000  retained=8000  alloc=13,419,045,864 ms=12182.5
 60d chat_calls=120000 retained=8000  alloc=27,297,668,608 ms=23769.7
（60d 工作集稳定 8000，不随年龄增长。）

docs/维护说明.md 新增 P27 小节记录上述现状与量级。不改任何模拟语义。
</content>
</entry>
<entry>
<title>perf(sim): M6a 谣言窗口扫描去中间表——最新在前早停递归替代 takeWhile/filter/sort，零分配且等价</title>
<updated>2026-09-21T15:53:40+00:00</updated>
<author>
<name>Somhairle H. Marisol</name>
<email>muqiu-han@outlook.com</email>
</author>
<published>2026-09-21T15:53:40+00:00</published>
<link rel='alternate' type='text/html' href='http://git.somhairle.bid/living-village.git/commit/?id=cc850bf7998daa0d785facaca59f89ec2aab6225'/>
<id>urn:sha1:cc850bf7998daa0d785facaca59f89ec2aab6225</id>
<content type='text'>
</content>
</entry>
</feed>
