@sushanglewis/lincoln 1.6.2 → 1.7.0
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.
- package/framework/.claude/agents/pm.md +2 -2
- package/framework/.claude/agents/security-reviewer.md +57 -0
- package/framework/.claude/harnesses/codex.yaml +31 -2
- package/framework/.claude/harnesses/command-map.yaml +4 -0
- package/framework/.claude/harnesses/opencode.yaml +33 -3
- package/framework/.claude/hooks/hooks.yaml +37 -0
- package/framework/.claude/hooks/on-session-start.sh +20 -5
- package/framework/.claude/hooks/on-stop.sh +22 -0
- package/framework/.claude/hooks/pre-tool-use.sh +22 -0
- package/framework/.claude/mcp/mcp.yaml +34 -0
- package/framework/.claude/policies/friction.yaml +18 -0
- package/framework/.claude/policies/security.yaml +46 -0
- package/framework/.claude/schemas/design-review-feedback.json +32 -0
- package/framework/.claude/schemas/stage-definition.schema.json +22 -0
- package/framework/.claude/skills/clarify-requirements/SKILL.md +1 -0
- package/framework/.claude/skills/clarify-requirements/prompts/main.md +83 -80
- package/framework/.claude/skills/draft-product-design/prompts/main.md +27 -14
- package/framework/.claude/stages/clarify.yaml +7 -5
- package/framework/.claude/stages/phase-1-p0-design.yaml +44 -0
- package/framework/.claude/stages/phase-1-p0-implement.yaml +47 -0
- package/framework/.claude/stages/phase-2-p1-design.yaml +53 -0
- package/framework/.claude/stages/phase-2-p1-implement.yaml +45 -0
- package/framework/.claude/stages/product-design-docs.yaml +6 -6
- package/framework/.claude/workflows/framework-self-improvement.yaml +100 -0
- package/framework/.claude/workflows/interview-to-knowledge.yaml +1 -0
- package/framework/.claude-plugin/marketplace.json +2 -2
- package/framework/.claude-plugin/plugin.json +1 -1
- package/framework/.version-bump.json +1 -1
- package/framework/README.en.md +24 -5
- package/framework/README.md +24 -5
- package/framework/RELEASE.md +41 -0
- package/framework/SKILL.md +15 -6
- package/framework/manifest.json +96 -56
- package/framework/scripts/check-harness-drift.sh +11 -1
- package/framework/scripts/lincoln-setup.py +17 -0
- package/framework/scripts/lincoln_condenser.py +110 -0
- package/framework/scripts/lincoln_friction.py +266 -0
- package/framework/scripts/lincoln_harness_adapter.py +185 -13
- package/framework/scripts/lincoln_mr_mine.py +146 -0
- package/framework/scripts/lincoln_recall.py +142 -0
- package/framework/scripts/lincoln_render.py +209 -6
- package/framework/scripts/lincoln_trace.py +119 -3
- package/framework/scripts/security_analyzer.py +234 -0
- package/framework/scripts/stage_loader.py +124 -1
- package/framework/tools/lincoln/package-lock.json +2 -2
- package/framework/tools/lincoln/package.json +1 -1
- package/framework/tools/lincoln-installer/package.json +6 -1
- package/package.json +6 -1
- package/framework/.claude/agents/external/everything-claude-code/agents/ecc-tdd-guide.md +0 -108
- package/framework/.claude/agents/external/oh-my-claudecode/agents/omc-architect.md +0 -134
- package/framework/.claude/agents/external/oh-my-claudecode/agents/omc-code-reviewer.md +0 -248
- package/framework/.claude/agents/external/oh-my-claudecode/agents/omc-designer.md +0 -122
- package/framework/.claude/agents/external/oh-my-claudecode/agents/omc-qa-tester.md +0 -106
- package/framework/.claude/agents/external/wshobson-agents/agents/wshobson-frontend-developer.md +0 -173
|
@@ -17,8 +17,8 @@ extends:
|
|
|
17
17
|
|
|
18
18
|
1. 与人类 PM 多轮对话,将访谈或 issue 输入转化为统一、可追溯、已确认的需求与设计方案。
|
|
19
19
|
2. 维护工作包门户 `index.html`:每新增或重命名一个文档/原型子页面,同步更新导航与「相关产物链接」表。
|
|
20
|
-
3. 维护跨子页面影响关系:PRD
|
|
21
|
-
4. 对 designer 的输入完整性负责:PRD
|
|
20
|
+
3. 维护跨子页面影响关系:PRD、用户故事、相关者分析、数据模型等核心文档变更时,在门户中标注受影响的设计文档与原型页面,使下游阶段知悉影响范围。
|
|
21
|
+
4. 对 designer 的输入完整性负责:PRD、用户故事、相关者分析、数据模型、流程图、页面地图必须完整、一致、无歧义;designer 回退确认时,PM 优先澄清,而非让 designer 自行假设。
|
|
22
22
|
5. 在 `product-prototype` 阶段以 reviewer 身份确认原型的功能、字段、流程与需求文档一致。
|
|
23
23
|
|
|
24
24
|
## 专属规则
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lc-security-reviewer
|
|
3
|
+
description: Lincoln 安全审查员角色,专注于框架策略、hook 门控与实现中的安全风险识别。
|
|
4
|
+
language: zh-CN
|
|
5
|
+
extends:
|
|
6
|
+
- agents/default.md
|
|
7
|
+
model: sonnet
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Lincoln Security Reviewer
|
|
11
|
+
|
|
12
|
+
你是 Lincoln 工作流中的安全审查员角色。本角色继承通用契约 [`agents/default.md`](agents/default.md),并补充以下安全专业职责。
|
|
13
|
+
|
|
14
|
+
## 关注点
|
|
15
|
+
|
|
16
|
+
1. **策略完整性**
|
|
17
|
+
- `.claude/policies/*.yaml` 是否覆盖关键风险面(删除、写入、外部调用、git 推送等)。
|
|
18
|
+
- 策略是否可绕过(前缀命令 `sudo`、`cd &&`、`env VAR=`、路径遍历等)。
|
|
19
|
+
|
|
20
|
+
2. **Hook 门控**
|
|
21
|
+
- `pre-tool-use.sh` 是否正确调用 `security_analyzer.py`。
|
|
22
|
+
- 危险操作(`rm -rf`、递归删除、绝对路径删除、git push)是否触发确认或阻断。
|
|
23
|
+
- 日志是否记录充分且不泄露敏感信息。
|
|
24
|
+
|
|
25
|
+
3. **Harness 分发安全**
|
|
26
|
+
- 生成到 codex / opencode 的适配产物是否保留安全策略语义。
|
|
27
|
+
- 默认关闭的能力(hooks/skills)是否确实没有在产物中留下痕迹。
|
|
28
|
+
|
|
29
|
+
4. **实现安全**
|
|
30
|
+
- 新增脚本是否验证输入、避免命令注入、避免路径遍历。
|
|
31
|
+
- 外部 API 调用是否经过允许列表或显式确认。
|
|
32
|
+
- 密钥、token 是否未硬编码。
|
|
33
|
+
|
|
34
|
+
## 输出格式
|
|
35
|
+
|
|
36
|
+
在 stage 评审中返回结构化反馈:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"risks": [
|
|
41
|
+
{
|
|
42
|
+
"severity": "critical|high|medium|low",
|
|
43
|
+
"category": "policy|hook|harness|implementation|secret",
|
|
44
|
+
"description": "风险描述",
|
|
45
|
+
"location": "文件路径:行号",
|
|
46
|
+
"recommendation": "修复建议"
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"approvable": true|false
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## 工作原则
|
|
54
|
+
|
|
55
|
+
- 不阻塞合法的研发活动,但对高危操作必须显式标记。
|
|
56
|
+
- 优先使用自动化检查(策略、测试),人工评审作为补充。
|
|
57
|
+
- 所有发现必须可追溯回具体文件与行号。
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
# codex harness manifest
|
|
2
2
|
# 生成:AGENTS.md(项目根,角色契约 + lc-* 命令清单 + 轻量门控)
|
|
3
3
|
# ~/.codex/prompts/lc-*.md(用户级斜杠命令)
|
|
4
|
+
# ~/.codex/skills/<skill>/SKILL.md(用户级技能)
|
|
4
5
|
# .codex-plugin/plugin.json(显式声明 hooks:{} 以关闭默认 hook 回退)
|
|
6
|
+
# .codex/rules/**/*.md(项目级规则)
|
|
7
|
+
# .codex/hooks/*.sh(项目级 hook)
|
|
8
|
+
# .codex/mcp.json(项目级 MCP 配置)
|
|
5
9
|
# spike 备注:codex 官方 docs 对 prompts frontmatter 描述不完整(网络受限),
|
|
6
10
|
# 采用稳妥约定:prompt 文件为纯 markdown 正文;若真实 CLI 验证不符,
|
|
7
11
|
# 移除 prompts target,命令说明已在 AGENTS.md 内联(回退方案零成本)。
|
|
@@ -13,8 +17,8 @@ capabilities:
|
|
|
13
17
|
# (superpowers codex hooks 陷阱 obra/superpowers@7d8d3d4——hooks 字段缺失时
|
|
14
18
|
# codex 回退到默认 hooks/hooks.json)。新增能力必须显式写出;空能力显式置 false,
|
|
15
19
|
# 不得省略字段。验收测试:tests/test_harness_default_off.py
|
|
16
|
-
hooks:
|
|
17
|
-
skills:
|
|
20
|
+
hooks: true
|
|
21
|
+
skills: true
|
|
18
22
|
agents: true # 经 AGENTS.md 拼接承载
|
|
19
23
|
commands: true
|
|
20
24
|
|
|
@@ -33,6 +37,31 @@ targets:
|
|
|
33
37
|
scope: home
|
|
34
38
|
transform: command-template
|
|
35
39
|
|
|
40
|
+
- kind: skill
|
|
41
|
+
source: .claude/skills/*/SKILL.md
|
|
42
|
+
output: "{home}/.codex/skills/{parent}/{name}.md"
|
|
43
|
+
scope: home
|
|
44
|
+
transform: copy
|
|
45
|
+
|
|
46
|
+
- kind: rule
|
|
47
|
+
source: .claude/rules/**/*.md
|
|
48
|
+
output: "{project}/.codex/rules/{relative_path}.md"
|
|
49
|
+
scope: project
|
|
50
|
+
transform: copy
|
|
51
|
+
optional: true
|
|
52
|
+
|
|
53
|
+
- kind: hook
|
|
54
|
+
source: .claude/hooks/*.sh
|
|
55
|
+
output: "{project}/.codex/hooks/{name}.sh"
|
|
56
|
+
scope: project
|
|
57
|
+
transform: copy
|
|
58
|
+
|
|
59
|
+
- kind: mcp
|
|
60
|
+
source: .claude/mcp/mcp.yaml
|
|
61
|
+
output: "{project}/.codex/mcp.json"
|
|
62
|
+
scope: project
|
|
63
|
+
transform: mcp-config
|
|
64
|
+
|
|
36
65
|
- kind: plugin
|
|
37
66
|
source: .claude-plugin/plugin.json
|
|
38
67
|
output: "{project}/.codex-plugin/{name}.json"
|
|
@@ -244,6 +244,10 @@ commands:
|
|
|
244
244
|
description: 已有源码项目的 Lincoln 迭代工作流
|
|
245
245
|
action: python3 "$LINCOLN_ROOT/scripts/lincoln_workflow.py"
|
|
246
246
|
args_hint: start --workflow existing-project-iteration
|
|
247
|
+
lc-wf-framework-self-improvement:
|
|
248
|
+
description: Lincoln 框架自身持续改进工作流(安全门控、harness 分发、摩擦学习、事件追踪、子代理委托)
|
|
249
|
+
action: python3 "$LINCOLN_ROOT/scripts/lincoln_workflow.py"
|
|
250
|
+
args_hint: start --workflow framework-self-improvement --issue-number <N>
|
|
247
251
|
lc-wf-interview-to-knowledge:
|
|
248
252
|
description: 从访谈录音到 GitHub Issues 再到 Obsidian 知识库沉淀的标准工作流
|
|
249
253
|
action: python3 "$LINCOLN_ROOT/scripts/lincoln_workflow.py"
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# opencode harness manifest
|
|
2
|
-
# 生成:.opencode/agent/*.md(角色)
|
|
2
|
+
# 生成:.opencode/agent/*.md(角色)
|
|
3
|
+
# .opencode/command/lc-*.md(命令)
|
|
4
|
+
# .opencode/skills/<skill>/SKILL.md(项目级技能)
|
|
5
|
+
# .opencode/rules/**/*.md(项目级规则)
|
|
6
|
+
# .opencode/hooks/*.sh(项目级 hook)
|
|
7
|
+
# .opencode/mcp.json(项目级 MCP 配置)
|
|
3
8
|
# spike 结论(Context7 /anomalyco/opencode):
|
|
4
9
|
# agent frontmatter 字段:description/mode/model/temperature/tools/permission
|
|
5
10
|
# command 文件:frontmatter(description/agent/model)+ 正文模板($ARGUMENTS)
|
|
@@ -10,8 +15,8 @@ capabilities:
|
|
|
10
15
|
# 缺省即关闭(#64):任何未显式声明的能力都可能被 harness 按默认值激活
|
|
11
16
|
# (superpowers codex hooks 陷阱 obra/superpowers@7d8d3d4)。新增能力必须显式写出;
|
|
12
17
|
# 空能力显式置 false,不得省略字段。验收测试:tests/test_harness_default_off.py
|
|
13
|
-
hooks:
|
|
14
|
-
skills:
|
|
18
|
+
hooks: true
|
|
19
|
+
skills: true
|
|
15
20
|
agents: true
|
|
16
21
|
commands: true
|
|
17
22
|
|
|
@@ -30,3 +35,28 @@ targets:
|
|
|
30
35
|
output: "{project}/.opencode/command/{name}.md"
|
|
31
36
|
scope: project
|
|
32
37
|
transform: command-template
|
|
38
|
+
|
|
39
|
+
- kind: skill
|
|
40
|
+
source: .claude/skills/*/SKILL.md
|
|
41
|
+
output: "{project}/.opencode/skills/{parent}/{name}.md"
|
|
42
|
+
scope: project
|
|
43
|
+
transform: copy
|
|
44
|
+
|
|
45
|
+
- kind: rule
|
|
46
|
+
source: .claude/rules/**/*.md
|
|
47
|
+
output: "{project}/.opencode/rules/{relative_path}.md"
|
|
48
|
+
scope: project
|
|
49
|
+
transform: copy
|
|
50
|
+
optional: true
|
|
51
|
+
|
|
52
|
+
- kind: hook
|
|
53
|
+
source: .claude/hooks/*.sh
|
|
54
|
+
output: "{project}/.opencode/hooks/{name}.sh"
|
|
55
|
+
scope: project
|
|
56
|
+
transform: copy
|
|
57
|
+
|
|
58
|
+
- kind: mcp
|
|
59
|
+
source: .claude/mcp/mcp.yaml
|
|
60
|
+
output: "{project}/.opencode/mcp.json"
|
|
61
|
+
scope: project
|
|
62
|
+
transform: mcp-config
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 1.0.0
|
|
3
|
+
description: |
|
|
4
|
+
Declarative hook registry for Lincoln.
|
|
5
|
+
Each entry declares the shell hook file, the events it handles, the harnesses
|
|
6
|
+
it applies to, and its execution order. Lower order values run first.
|
|
7
|
+
|
|
8
|
+
hooks:
|
|
9
|
+
- name: pre-tool-use
|
|
10
|
+
file: pre-tool-use.sh
|
|
11
|
+
events: [pre_tool_use]
|
|
12
|
+
harnesses: [claude-code, codex, opencode]
|
|
13
|
+
order: 10
|
|
14
|
+
|
|
15
|
+
- name: on-session-start
|
|
16
|
+
file: on-session-start.sh
|
|
17
|
+
events: [session_start]
|
|
18
|
+
harnesses: [claude-code]
|
|
19
|
+
order: 10
|
|
20
|
+
|
|
21
|
+
- name: on-stop
|
|
22
|
+
file: on-stop.sh
|
|
23
|
+
events: [session_stop]
|
|
24
|
+
harnesses: [claude-code]
|
|
25
|
+
order: 10
|
|
26
|
+
|
|
27
|
+
- name: post-tool-use
|
|
28
|
+
file: post-tool-use.sh
|
|
29
|
+
events: [post_tool_use]
|
|
30
|
+
harnesses: [claude-code]
|
|
31
|
+
order: 10
|
|
32
|
+
|
|
33
|
+
- name: on-pr-event
|
|
34
|
+
file: on-pr-event.sh
|
|
35
|
+
events: [pull_request]
|
|
36
|
+
harnesses: [claude-code]
|
|
37
|
+
order: 10
|
|
@@ -263,7 +263,22 @@ echo "Design ID: ${DESIGN_ID:-(unset)}"
|
|
|
263
263
|
echo "Waiting for: $WAITING_FOR"
|
|
264
264
|
echo ""
|
|
265
265
|
|
|
266
|
-
# 4.
|
|
266
|
+
# 4. Recall relevant knowledge before injecting full context.
|
|
267
|
+
RECALL_JSON=$("$PYTHON" "$FRAMEWORK_ROOT/scripts/lincoln_recall.py" \
|
|
268
|
+
--query "$CURRENT_STAGE" \
|
|
269
|
+
--top-k 5 \
|
|
270
|
+
--format json \
|
|
271
|
+
2>/dev/null || echo '{"docs":[]}')
|
|
272
|
+
_RECALL_COUNT=$(echo "$RECALL_JSON" | "$PYTHON" -c "import sys,json; print(len(json.load(sys.stdin).get('docs',[])))" 2>/dev/null || echo 0)
|
|
273
|
+
if [[ "$_RECALL_COUNT" -gt 0 ]]; then
|
|
274
|
+
echo "=== Lincoln 相关知识 ==="
|
|
275
|
+
echo "$RECALL_JSON" | "$PYTHON" -c "import sys,json; docs=json.load(sys.stdin).get('docs',[]); [print(f'- [{d[\"title\"]}]({d[\"path\"]}) — score {d[\"score\"]}') for d in docs]"
|
|
276
|
+
echo ""
|
|
277
|
+
echo "=== End Lincoln 相关知识 ==="
|
|
278
|
+
echo ""
|
|
279
|
+
fi
|
|
280
|
+
|
|
281
|
+
# 5. Load stage context, agent role, and workflow template (summaries only)
|
|
267
282
|
if [[ "$CURRENT_STAGE" != "not_started" ]]; then
|
|
268
283
|
STAGE_YAML="$FRAMEWORK_ROOT/.claude/stages/$CURRENT_STAGE.yaml"
|
|
269
284
|
if [[ -f "$STAGE_YAML" ]]; then
|
|
@@ -339,7 +354,7 @@ else
|
|
|
339
354
|
NEEDS_OPENING_GUIDANCE="true"
|
|
340
355
|
fi
|
|
341
356
|
|
|
342
|
-
#
|
|
357
|
+
# 6. Load Conductor / OMC context
|
|
343
358
|
if [[ -d "$ROOT/.context" || -d "$ROOT/.omc" ]]; then
|
|
344
359
|
echo "=== Conductor / OMC Context ==="
|
|
345
360
|
for dir in "$ROOT/.context" "$ROOT/.omc"; do
|
|
@@ -362,7 +377,7 @@ if [[ -d "$ROOT/.context" || -d "$ROOT/.omc" ]]; then
|
|
|
362
377
|
echo ""
|
|
363
378
|
fi
|
|
364
379
|
|
|
365
|
-
#
|
|
380
|
+
# 7. Read last node handoff
|
|
366
381
|
HANDOFF_FILE=""
|
|
367
382
|
if [[ "$LAST_NODE" != "{}" ]]; then
|
|
368
383
|
HANDOFF_FILE=$(echo "$LAST_NODE" | "$PYTHON" -c "import sys,json; print(json.load(sys.stdin).get('handoff_file',''))" 2>/dev/null || echo "")
|
|
@@ -387,7 +402,7 @@ if [[ -n "$PROCESS_SLUG" && -d "$ROOT/$PROCESS_SLUG/handoffs" ]]; then
|
|
|
387
402
|
fi
|
|
388
403
|
fi
|
|
389
404
|
|
|
390
|
-
#
|
|
405
|
+
# 8. Run status summary
|
|
391
406
|
STATUS_OUTPUT=$("$PYTHON" "$FRAMEWORK_ROOT/scripts/lincoln-status.py" --format markdown --state-file "$STATE_FILE" 2>/dev/null) || STATUS_OUTPUT=""
|
|
392
407
|
if [[ -n "$STATUS_OUTPUT" ]]; then
|
|
393
408
|
echo "=== Lincoln Status Summary ==="
|
|
@@ -396,7 +411,7 @@ if [[ -n "$STATUS_OUTPUT" ]]; then
|
|
|
396
411
|
echo ""
|
|
397
412
|
fi
|
|
398
413
|
|
|
399
|
-
#
|
|
414
|
+
# 9. Opening guidance for a work package that has not started yet
|
|
400
415
|
if [[ "${NEEDS_OPENING_GUIDANCE:-}" == "true" ]]; then
|
|
401
416
|
_LINCOLN_GUIDANCE_INJECTED="true"
|
|
402
417
|
echo "=== Lincoln 开场引导 ==="
|
|
@@ -101,4 +101,26 @@ if [[ -n "$CURRENT_STAGE" && ( "$STAGE_STATUS" == "waiting_for_human" || "$STAGE
|
|
|
101
101
|
>/dev/null 2>&1 || true
|
|
102
102
|
fi
|
|
103
103
|
|
|
104
|
+
# Record session stop lifecycle event (best-effort).
|
|
105
|
+
"$PYTHON" - "$STATE_FILE" "$FRAMEWORK_ROOT" <<'PY' >/dev/null 2>&1 || true
|
|
106
|
+
import sys
|
|
107
|
+
sys.path.insert(0, sys.argv[2])
|
|
108
|
+
from pathlib import Path
|
|
109
|
+
from scripts import lincoln_trace
|
|
110
|
+
lincoln_trace.append_event_entry(
|
|
111
|
+
Path(sys.argv[1]),
|
|
112
|
+
"session",
|
|
113
|
+
{"event_type": "session_ended"},
|
|
114
|
+
)
|
|
115
|
+
PY
|
|
116
|
+
|
|
117
|
+
# Score session friction asynchronously; failures must not block hook exit.
|
|
118
|
+
(
|
|
119
|
+
"$PYTHON" "$FRAMEWORK_ROOT/scripts/lincoln_friction.py" \
|
|
120
|
+
--root "$FRAMEWORK_ROOT" \
|
|
121
|
+
--state-file "$STATE_FILE" \
|
|
122
|
+
--tail-lines 500 \
|
|
123
|
+
>/dev/null 2>&1 || true
|
|
124
|
+
) &
|
|
125
|
+
|
|
104
126
|
exit 0
|
|
@@ -220,6 +220,28 @@ if [[ "$STAGE_STATUS" == "not_started" || "$STAGE_STATUS" == "entry_validating"
|
|
|
220
220
|
fi
|
|
221
221
|
fi
|
|
222
222
|
|
|
223
|
+
# SecurityAnalyzer: evaluate side-effect tools against risk policy.
|
|
224
|
+
# File deletion requires explicit human confirmation; git push / API calls are logged.
|
|
225
|
+
if is_side_effect "$TOOL_NAME"; then
|
|
226
|
+
SECURITY_LOG_DIR="$FRAMEWORK_ROOT/$PROCESS_SLUG/logs"
|
|
227
|
+
SECURITY_RESULT=$("$PYTHON" "$FRAMEWORK_ROOT/scripts/security_analyzer.py" \
|
|
228
|
+
--root "$FRAMEWORK_ROOT" \
|
|
229
|
+
--tool "$TOOL_NAME" \
|
|
230
|
+
--args "$TOOL_ARGS" \
|
|
231
|
+
--process-slug "$PROCESS_SLUG" \
|
|
232
|
+
--log-dir "$SECURITY_LOG_DIR" \
|
|
233
|
+
2>/dev/null || echo '{"level":"unknown","confirm_required":true,"message":"Security analyzer failed."}')
|
|
234
|
+
|
|
235
|
+
CONFIRM_REQUIRED=$(echo "$SECURITY_RESULT" | "$PYTHON" -c 'import sys,json; print(json.load(sys.stdin).get("confirm_required", False))')
|
|
236
|
+
SECURITY_MESSAGE=$(echo "$SECURITY_RESULT" | "$PYTHON" -c 'import sys,json; print(json.load(sys.stdin).get("message", ""))')
|
|
237
|
+
|
|
238
|
+
if [[ "$CONFIRM_REQUIRED" == "True" ]]; then
|
|
239
|
+
echo "BLOCKED: $SECURITY_MESSAGE" >&2
|
|
240
|
+
echo "Run: $PYTHON $FRAMEWORK_ROOT/scripts/stage_loader.py --stage $CURRENT_STAGE --action approve-gate --approved-by human-pm" >&2
|
|
241
|
+
exit 1
|
|
242
|
+
fi
|
|
243
|
+
fi
|
|
244
|
+
|
|
223
245
|
# When paused/waiting_for_human/validation_failed, only allow read-only tools
|
|
224
246
|
if [[ "$STAGE_STATUS" == "paused" || "$STAGE_STATUS" == "waiting_for_human" || "$STAGE_STATUS" == "validation_failed" ]]; then
|
|
225
247
|
if [[ "$TOOL_NAME" != "Read" && "$TOOL_NAME" != "Grep" && "$TOOL_NAME" != "Glob" ]]; then
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 1.0.0
|
|
3
|
+
description: |
|
|
4
|
+
Declarative MCP server configuration for Lincoln.
|
|
5
|
+
This file is the single source of truth; `scripts/lincoln_harness_adapter.py`
|
|
6
|
+
distributes it to Codex / OpenCode harnesses in their native formats.
|
|
7
|
+
Sensitive values use `${VAR}` placeholders and are resolved from `.env` or the
|
|
8
|
+
runtime environment. Never commit real secrets.
|
|
9
|
+
|
|
10
|
+
servers:
|
|
11
|
+
pencil:
|
|
12
|
+
command: npx
|
|
13
|
+
args:
|
|
14
|
+
- "-y"
|
|
15
|
+
- "@pencil/mcp-server"
|
|
16
|
+
env:
|
|
17
|
+
PENCIL_API_KEY: ${PENCIL_API_KEY}
|
|
18
|
+
enabled: true
|
|
19
|
+
description: Pencil design-file MCP server for .pen import/export.
|
|
20
|
+
harness_overrides:
|
|
21
|
+
codex:
|
|
22
|
+
enabled: false
|
|
23
|
+
opencode:
|
|
24
|
+
enabled: false
|
|
25
|
+
|
|
26
|
+
github:
|
|
27
|
+
command: npx
|
|
28
|
+
args:
|
|
29
|
+
- "-y"
|
|
30
|
+
- "@modelcontextprotocol/server-github"
|
|
31
|
+
env:
|
|
32
|
+
GITHUB_PERSONAL_ACCESS_TOKEN: ${GITHUB_PERSONAL_ACCESS_TOKEN}
|
|
33
|
+
enabled: true
|
|
34
|
+
description: GitHub operations - issues, PRs, repos.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
schema_version: 1.0.0
|
|
2
|
+
thresholds:
|
|
3
|
+
prompt_user: 5
|
|
4
|
+
auto_suggest: 3
|
|
5
|
+
weights:
|
|
6
|
+
tool_failed: 2
|
|
7
|
+
tool_rejected: 3
|
|
8
|
+
retry_spike: 3
|
|
9
|
+
human_override: 5
|
|
10
|
+
long_session: 1
|
|
11
|
+
long_session_minutes: 30
|
|
12
|
+
retry_count_threshold: 3
|
|
13
|
+
signals:
|
|
14
|
+
- tool_failed
|
|
15
|
+
- tool_rejected
|
|
16
|
+
- retry_spike
|
|
17
|
+
- human_override
|
|
18
|
+
- long_session
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
schema_version: 1.0.0
|
|
2
|
+
policies:
|
|
3
|
+
- name: recursive-delete
|
|
4
|
+
tool: Bash
|
|
5
|
+
condition: 'command matches "rm -r" or "rm -rf"'
|
|
6
|
+
level: high
|
|
7
|
+
message: "递归删除风险极高,需人工确认。"
|
|
8
|
+
confirm: true
|
|
9
|
+
|
|
10
|
+
- name: file-deletion
|
|
11
|
+
tool: Bash
|
|
12
|
+
condition: 'command matches any of ["rm", "rmdir"]'
|
|
13
|
+
level: high
|
|
14
|
+
message: "文件/目录删除操作不可逆,需人工确认。"
|
|
15
|
+
confirm: true
|
|
16
|
+
|
|
17
|
+
- name: git-push
|
|
18
|
+
tool: Bash
|
|
19
|
+
condition: 'command matches "git push"'
|
|
20
|
+
level: medium
|
|
21
|
+
message: "git push 将改变远程仓库状态。"
|
|
22
|
+
confirm: false
|
|
23
|
+
log: true
|
|
24
|
+
|
|
25
|
+
- name: external-api-call
|
|
26
|
+
tool: Bash
|
|
27
|
+
condition: 'command matches any external HTTP client (curl, wget, httpie)'
|
|
28
|
+
level: medium
|
|
29
|
+
message: "正在调用外部 API。"
|
|
30
|
+
confirm: false
|
|
31
|
+
log: true
|
|
32
|
+
|
|
33
|
+
- name: file-write-outside-process
|
|
34
|
+
tool: Write|Edit
|
|
35
|
+
condition: "target outside current process_slug"
|
|
36
|
+
level: high
|
|
37
|
+
message: "不允许写入当前 issue 工作包之外的产物目录。"
|
|
38
|
+
confirm: true
|
|
39
|
+
|
|
40
|
+
- name: file-write-inside-process
|
|
41
|
+
tool: Write|Edit
|
|
42
|
+
condition: "target inside current process_slug"
|
|
43
|
+
level: medium
|
|
44
|
+
message: "写入当前 issue 工作包内的文件。"
|
|
45
|
+
confirm: false
|
|
46
|
+
log: true
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "Design Review Feedback",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"required": ["findings"],
|
|
6
|
+
"properties": {
|
|
7
|
+
"findings": {
|
|
8
|
+
"type": "array",
|
|
9
|
+
"items": {
|
|
10
|
+
"type": "object",
|
|
11
|
+
"required": ["severity", "summary"],
|
|
12
|
+
"properties": {
|
|
13
|
+
"severity": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"enum": ["critical", "high", "medium", "low"]
|
|
16
|
+
},
|
|
17
|
+
"summary": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"maxLength": 500
|
|
20
|
+
},
|
|
21
|
+
"file": {
|
|
22
|
+
"type": "string"
|
|
23
|
+
},
|
|
24
|
+
"recommendation": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"maxLength": 1000
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -100,6 +100,28 @@
|
|
|
100
100
|
{ "type": "null" }
|
|
101
101
|
],
|
|
102
102
|
"description": "Agent role to hand off to at stage end"
|
|
103
|
+
},
|
|
104
|
+
"parallel_specialists": {
|
|
105
|
+
"type": "array",
|
|
106
|
+
"items": {
|
|
107
|
+
"type": "string",
|
|
108
|
+
"pattern": "^[a-z][a-z0-9-]*$"
|
|
109
|
+
},
|
|
110
|
+
"default": [],
|
|
111
|
+
"description": "Specialist agents that may be invoked in parallel during this stage"
|
|
112
|
+
},
|
|
113
|
+
"merge_strategy": {
|
|
114
|
+
"type": "string",
|
|
115
|
+
"enum": ["priority", "vote", "consensus"],
|
|
116
|
+
"default": "priority",
|
|
117
|
+
"description": "How to combine outputs from parallel specialists"
|
|
118
|
+
},
|
|
119
|
+
"output_schema": {
|
|
120
|
+
"oneOf": [
|
|
121
|
+
{ "type": "string", "minLength": 1 },
|
|
122
|
+
{ "type": "null" }
|
|
123
|
+
],
|
|
124
|
+
"description": "JSON Schema path for structured specialist outputs"
|
|
103
125
|
}
|
|
104
126
|
},
|
|
105
127
|
"additionalProperties": false
|
|
@@ -10,6 +10,7 @@ inputs:
|
|
|
10
10
|
required: true
|
|
11
11
|
outputs:
|
|
12
12
|
- "{process_slug}/pages/docs/requirements.html"
|
|
13
|
+
- "{process_slug}/pages/docs/stakeholders.html"
|
|
13
14
|
- "{process_slug}/pages/docs/user-stories.html"
|
|
14
15
|
- "{process_slug}/pages/docs/prd.html"
|
|
15
16
|
- "{process_slug}/pages/docs/snapshots/prd-v*.html"
|