fix: close review findings in context memory, attack chain and blackboard

Attack chain: failure text goes to textContent, so opt out of i18next
interpolation escaping that rendered upstream errors as //";
give regenerate its own message key; keep the summary card expanded across
a 409 refresh; probe for a cached graph before parsing last_react_input so
polling no longer re-reads a multi-megabyte column; hide the card in the
node-details exclusive state and bound it on narrow screens; drop the dead
hardcoded Chinese title from the API payload.

Blackboard: stop mirroring note/context-* keys into the fact body links
section, which get_project_fact returns verbatim without scope filtering;
single-line category and confidence in index rows so a newline cannot inject
a fake row; make the path overview fail closed on an empty index set.

Provenance: reuse fitUserIntentLedgerText when sanitizing a ledger entry so
a single entry cannot exceed its cap by the three ellipsis runes.

The .cjs harness now escapes interpolated values like real i18next, so the
existing XSS test also pins the escapeValue opt-out.
This commit is contained in:
Sycun committed 2026-10-12 23:16:33 +08:00
1 parent 2b76b31355
commit 16189e0b76
21 files changed
+253 -40

No files matched your search

+4 -4
View File
@@ -71,8 +71,8 @@ func (h *AttackChainHandler) GetAttackChain(c *gin.Context) {
// 先尝试从数据库加载(如果已生成过)
openAIConfig := h.getOpenAIConfig()
builder := attackchain.NewBuilder(h.db, openAIConfig, h.logger)
chain, err := builder.LoadChainFromDatabase(conversationID)
if err == nil && len(chain.Nodes) > 0 {
chain, err := builder.LoadCachedChainIfPresent(conversationID)
if err == nil && chain != nil {
// 如果已存在,直接返回
h.logger.Info("返回已存在的攻击链", zap.String("conversationId", conversationID))
c.JSON(http.StatusOK, chain)
@@ -94,8 +94,8 @@ func (h *AttackChainHandler) GetAttackChain(c *gin.Context) {
defer lock.Unlock()
// 再次检查是否已生成(可能在等待锁的过程中已经生成完成)
chain, err = builder.LoadChainFromDatabase(conversationID)
if err == nil && len(chain.Nodes) > 0 {
chain, err = builder.LoadCachedChainIfPresent(conversationID)
if err == nil && chain != nil {
h.logger.Info("返回已存在的攻击链(在锁等待期间已生成)", zap.String("conversationId", conversationID))
c.JSON(http.StatusOK, chain)
return