@frankzhang2026/opencode-android-orchestrator 1.0.4 → 1.0.5
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/CHANGELOG.md +11 -0
- package/README.md +8 -8
- package/dist/installer/adaptive-templates.d.ts +1 -1
- package/dist/installer/adaptive-templates.d.ts.map +1 -1
- package/dist/installer/adaptive-templates.js +11 -0
- package/dist/installer/adaptive-templates.js.map +1 -1
- package/dist/installer/opencode-config.d.ts +3 -3
- package/dist/installer/opencode-config.js +1 -1
- package/dist/queue/queue.d.ts.map +1 -1
- package/dist/queue/queue.js +56 -0
- package/dist/queue/queue.js.map +1 -1
- package/docs/MIGRATION.md +8 -8
- package/docs/QUEUE.md +21 -1
- package/docs/SECURITY.md +1 -1
- package/docs/TROUBLESHOOTING.md +7 -7
- package/package.json +1 -1
- package/templates/.opencode/agents/scheduled-coder.md +9 -0
- package/templates/.opencode/agents/scheduled-planner.md +10 -0
- package/templates/.opencode/skills/scheduled-quality-coder/SKILL.md +7 -1
- package/templates/.opencode/skills/scheduled-quality-reviewer/SKILL.md +4 -0
- package/templates/automation/task-contract.schema.json +76 -4
- package/templates/automation/tasks/TASK-TEMPLATE.json.example +25 -2
- package/templates/scripts/automation/acceptance-report.sh +12 -0
- package/templates/scripts/automation/lib.sh +108 -0
- package/templates/scripts/automation/record-red.sh +170 -32
- package/templates/scripts/automation/show-acceptance-review.sh +7 -0
- package/templates/scripts/automation/status.sh +6 -0
- package/templates/scripts/automation/validate-contract.sh +46 -2
- package/templates/scripts/automation/verify-task.sh +14 -0
|
@@ -79,6 +79,13 @@ jq -r '.nonGoals[] | "- \(.)"' "$report_file"
|
|
|
79
79
|
|
|
80
80
|
printf '\n### P1 · 自动证据是否可信\n\n'
|
|
81
81
|
printf -- '- RED 退出码:`%s`(应为非 0,证明测试先真实失败)\n' "$(jq -r '.evidence.redExitCode' "$report_file")"
|
|
82
|
+
if [[ "$(jq -r '.evidence.structuredRed != null' "$report_file")" == "true" ]]; then
|
|
83
|
+
printf -- '- 结构化 RED:声明 `%s` 个,用例匹配 `%s` 个,额外用例 `%s` 个\n' \
|
|
84
|
+
"$(jq -r '.evidence.structuredRed.summary.declared' "$report_file")" \
|
|
85
|
+
"$(jq -r '.evidence.structuredRed.summary.valid' "$report_file")" \
|
|
86
|
+
"$(jq -r '.evidence.structuredRed.summary.undeclared' "$report_file")"
|
|
87
|
+
jq -r '.evidence.structuredRed.cases[] | " - `\(.id)` · \(.intent) · 修改前应 \(.expectedBefore) · 已核验 \(.valid)"' "$report_file"
|
|
88
|
+
fi
|
|
82
89
|
printf -- '- 质量门:`%s`,第 %s 个编码周期内共运行 %s 次\n' \
|
|
83
90
|
"$(jq -r '.evidence.qualityGate' "$report_file")" \
|
|
84
91
|
"$(jq -r '.evidence.codingCycle' "$report_file")" \
|
|
@@ -21,6 +21,8 @@ workspace_json="$(if [[ -f "$workspace_file" ]]; then jq -c . "$workspace_file";
|
|
|
21
21
|
origin_json="$(if [[ -f "$origin_file" ]]; then jq -c . "$origin_file"; else printf 'null'; fi)"
|
|
22
22
|
baseline_json="$(if [[ -f "$evidence_dir/baseline.json" ]]; then jq -c . "$evidence_dir/baseline.json"; else printf 'null'; fi)"
|
|
23
23
|
red_json="$(if [[ -f "$evidence_dir/red.json" ]]; then jq -c . "$evidence_dir/red.json"; else printf 'null'; fi)"
|
|
24
|
+
preflight_json="$(if [[ -f "$evidence_dir/test-preflight.json" ]]; then jq -c . "$evidence_dir/test-preflight.json"; else printf 'null'; fi)"
|
|
25
|
+
manifest_json="$(if [[ -f "$evidence_dir/test-manifest.json" ]]; then jq -c . "$evidence_dir/test-manifest.json"; else printf 'null'; fi)"
|
|
24
26
|
ready_json="$(if [[ -f "$evidence_dir/ready.json" ]]; then jq -c . "$evidence_dir/ready.json"; else printf 'null'; fi)"
|
|
25
27
|
review_json="$(if [[ -f "$evidence_dir/review.json" ]]; then jq -c . "$evidence_dir/review.json"; else printf 'null'; fi)"
|
|
26
28
|
gate_json=null
|
|
@@ -93,6 +95,8 @@ jq -n \
|
|
|
93
95
|
--argjson origin "$origin_json" \
|
|
94
96
|
--argjson baseline "$baseline_json" \
|
|
95
97
|
--argjson red "$red_json" \
|
|
98
|
+
--argjson testPreflight "$preflight_json" \
|
|
99
|
+
--argjson testManifest "$manifest_json" \
|
|
96
100
|
--argjson ready "$ready_json" \
|
|
97
101
|
--argjson gate "$gate_json" \
|
|
98
102
|
--argjson review "$review_json" \
|
|
@@ -118,6 +122,8 @@ jq -n \
|
|
|
118
122
|
directory: $evidence,
|
|
119
123
|
baseline: $baseline,
|
|
120
124
|
red: $red,
|
|
125
|
+
testPreflight: $testPreflight,
|
|
126
|
+
testManifest: $testManifest,
|
|
121
127
|
ready: $ready,
|
|
122
128
|
latestGate: $gate,
|
|
123
129
|
review: $review,
|
|
@@ -27,7 +27,7 @@ fi
|
|
|
27
27
|
jq -e . "$contract" >/dev/null || automation_die "contract is not valid JSON: $contract"
|
|
28
28
|
|
|
29
29
|
jq -e '
|
|
30
|
-
(.schemaVersion == 1 or .schemaVersion == 2) and
|
|
30
|
+
(.schemaVersion == 1 or .schemaVersion == 2 or .schemaVersion == 3) and
|
|
31
31
|
(.id | type == "string" and test("^TASK-[A-Z0-9-]+$")) and
|
|
32
32
|
(.title | type == "string" and length > 0) and
|
|
33
33
|
.designApproved == true and
|
|
@@ -53,7 +53,51 @@ jq -e '
|
|
|
53
53
|
([.targetTests[].filter] | length == (unique | length)) and
|
|
54
54
|
(.deviceTestsRequired | type == "boolean") and
|
|
55
55
|
(.testPolicy == "required" or .testPolicy == "not-required") and
|
|
56
|
-
(if .testPolicy == "not-required" then (.testPolicyReason | type == "string" and length >= 20) else true end)
|
|
56
|
+
(if .testPolicy == "not-required" then (.testPolicyReason | type == "string" and length >= 20) else true end) and
|
|
57
|
+
(if .schemaVersion == 3 then
|
|
58
|
+
(.acceptanceCriteria | length) as $criterionCount |
|
|
59
|
+
(.targetTests | length) as $targetCount |
|
|
60
|
+
(.verification | type == "object" and
|
|
61
|
+
keys == ["cases", "maxPreparationFixes", "version"] and
|
|
62
|
+
.version == 1 and
|
|
63
|
+
(.maxPreparationFixes | type == "number" and floor == . and . >= 0 and . <= 1) and
|
|
64
|
+
(.cases | type == "array" and length > 0) and
|
|
65
|
+
([.cases[].id] | length == (unique | length)) and
|
|
66
|
+
([.cases[] | [.test.target, .test.className, .test.name] | @json] | length == (unique | length)) and
|
|
67
|
+
(any(.cases[]; .intent == "change")) and
|
|
68
|
+
all(.cases[];
|
|
69
|
+
type == "object" and
|
|
70
|
+
([keys[]] - ["id", "criterion", "intent", "before", "after", "source", "test", "expectedFailure"] | length == 0) and
|
|
71
|
+
(.id | type == "string" and test("^[A-Z][A-Z0-9-]{2,63}$")) and
|
|
72
|
+
(.criterion | type == "number" and floor == . and . >= 1 and . <= $criterionCount) and
|
|
73
|
+
.after == "pass" and
|
|
74
|
+
(.test | type == "object" and keys == ["className", "name", "target"] and
|
|
75
|
+
(.target | type == "number" and floor == . and . >= 0 and . < $targetCount) and
|
|
76
|
+
(.className | type == "string" and length > 0) and
|
|
77
|
+
(.name | type == "string" and length > 0)) and
|
|
78
|
+
(if .intent == "preserve" then
|
|
79
|
+
.before == "pass" and
|
|
80
|
+
(.source == "existingTest" or .source == "baselineCapture" or .source == "measuredFact") and
|
|
81
|
+
(has("expectedFailure") | not)
|
|
82
|
+
elif .intent == "change" then
|
|
83
|
+
.before == "fail" and .source == "userRequirement" and
|
|
84
|
+
(.expectedFailure | type == "object" and
|
|
85
|
+
([keys[]] - ["type", "messageIncludes", "origin"] | length == 0) and
|
|
86
|
+
(.type | type == "string" and length > 0) and
|
|
87
|
+
(.origin | type == "string" and length >= 12) and
|
|
88
|
+
(if has("messageIncludes") then (.messageIncludes | type == "string" and length >= 3) else true end))
|
|
89
|
+
elif .intent == "observe" then
|
|
90
|
+
.before == "observe" and
|
|
91
|
+
(.source == "userRequirement" or .source == "existingTest" or .source == "baselineCapture" or .source == "measuredFact") and
|
|
92
|
+
(if has("expectedFailure") then
|
|
93
|
+
(.expectedFailure | type == "object" and
|
|
94
|
+
([keys[]] - ["type", "messageIncludes", "origin"] | length == 0) and
|
|
95
|
+
(.type | type == "string" and length > 0) and
|
|
96
|
+
(.origin | type == "string" and length >= 12) and
|
|
97
|
+
(if has("messageIncludes") then (.messageIncludes | type == "string" and length >= 3) else true end))
|
|
98
|
+
else true end)
|
|
99
|
+
else false end)))
|
|
100
|
+
else true end)
|
|
57
101
|
' "$contract" >/dev/null || automation_die "contract is missing required fields or violates limits"
|
|
58
102
|
|
|
59
103
|
task_id="$(jq -r '.id' "$contract")"
|
|
@@ -15,6 +15,20 @@ evidence_dir="$(automation_evidence_path "$task_id")"
|
|
|
15
15
|
[[ -f "$evidence_dir/baseline.json" ]] || { automation_die "baseline evidence is missing"; exit 41; }
|
|
16
16
|
[[ -f "$evidence_dir/red.json" ]] || { automation_die "RED evidence is missing"; exit 41; }
|
|
17
17
|
|
|
18
|
+
contract_schema="$(jq -er '.schemaVersion' "$contract")"
|
|
19
|
+
if [[ "$contract_schema" == "3" ]]; then
|
|
20
|
+
preflight_meta="$evidence_dir/test-preflight.json"
|
|
21
|
+
manifest_meta="$evidence_dir/test-manifest.json"
|
|
22
|
+
red_meta="$evidence_dir/red.json"
|
|
23
|
+
[[ -f "$preflight_meta" && -f "$manifest_meta" ]] || { automation_die "structured RED evidence is incomplete"; exit 41; }
|
|
24
|
+
[[ "$(jq -er '.valid' "$preflight_meta")" == "true" ]] || { automation_die "structured RED preflight was not valid"; exit 41; }
|
|
25
|
+
[[ "$(jq -er '.contractSha256' "$red_meta")" == "$(automation_file_sha256 "$contract")" ]] || { automation_die "RED contract binding changed"; exit 41; }
|
|
26
|
+
[[ "$(jq -er '.baselineHead' "$red_meta")" == "$(jq -er '.head' "$evidence_dir/baseline.json")" ]] || { automation_die "RED baseline binding changed"; exit 41; }
|
|
27
|
+
[[ "$(jq -er '.testDiffSha256' "$red_meta")" == "$(automation_test_diff_sha "$task_id" "$AUTOMATION_ROOT")" ]] || { automation_die "tests changed after structured RED"; exit 41; }
|
|
28
|
+
[[ "$(jq -er '.preflightSha256' "$red_meta")" == "$(automation_file_sha256 "$preflight_meta")" ]] || { automation_die "RED preflight evidence changed"; exit 41; }
|
|
29
|
+
[[ "$(jq -er '.manifestSha256' "$red_meta")" == "$(automation_file_sha256 "$manifest_meta")" ]] || { automation_die "RED test manifest changed"; exit 41; }
|
|
30
|
+
fi
|
|
31
|
+
|
|
18
32
|
"$SCRIPT_DIR/scope-gate.sh" "$task_id"
|
|
19
33
|
|
|
20
34
|
automation_run_configured_unit_tests "$contract" "$AUTOMATION_ROOT"
|