vibe-coding-master 0.7.43 → 0.7.45
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/README.md +64 -39
- package/dist/backend/adapters/claude-adapter.js +2 -2
- package/dist/backend/adapters/codex-bridge-adapter.js +213 -0
- package/dist/backend/api/app-settings-routes.js +6 -6
- package/dist/backend/api/artifact-routes.js +3 -0
- package/dist/backend/api/harness-routes.js +16 -0
- package/dist/backend/api/task-routes.js +1 -0
- package/dist/backend/api/workflow-control-routes.js +12 -0
- package/dist/backend/cli/install-vcm-harness.js +21 -0
- package/dist/backend/server.js +11 -9
- package/dist/backend/services/app-settings-service.js +11 -11
- package/dist/backend/services/artifact-service.js +7 -30
- package/dist/backend/services/auto-memory-service.js +640 -12
- package/dist/backend/services/claude-hook-service.js +80 -2
- package/dist/backend/services/{ccr-integration-service.js → codex-bridge-integration-service.js} +71 -71
- package/dist/backend/services/gate-review-service.js +173 -74
- package/dist/backend/services/harness-feedback-service.js +76 -78
- package/dist/backend/services/harness-service.js +27 -3
- package/dist/backend/services/runtime-coordinator-service.js +2 -1
- package/dist/backend/services/session-service.js +16 -16
- package/dist/backend/services/status-service.js +1 -0
- package/dist/backend/services/translation-worker-service.js +19 -4
- package/dist/backend/services/usage-analytics-service.js +3 -3
- package/dist/backend/services/workflow-control-service.js +96 -12
- package/dist/backend/templates/handoff.js +44 -2
- package/dist/backend/templates/harness/architect-agent.js +13 -7
- package/dist/backend/templates/harness/architect-scaffold-worker-agent.js +1 -1
- package/dist/backend/templates/harness/check-scaffold-ledger.js +234 -10
- package/dist/backend/templates/harness/claude-root.js +3 -2
- package/dist/backend/templates/harness/coder-agent.js +8 -0
- package/dist/backend/templates/harness/gate-review.js +144 -49
- package/dist/backend/templates/harness/harness-engineer-agent.js +25 -10
- package/dist/backend/templates/harness/project-manager-agent.js +16 -10
- package/dist/backend/templates/harness/resolve-durable-doc-assignment.js +60 -0
- package/dist/backend/templates/harness/tester-agent.js +13 -0
- package/dist/backend/templates/harness/vcm-ask-user-skill.js +82 -0
- package/dist/backend/templates/harness/vcm-code-navigation-skill.js +7 -5
- package/dist/backend/templates/harness/vcm-task-state-skill.js +2 -2
- package/dist/backend/templates/harness/vcm-workflow-review-skill.js +1 -1
- package/dist/shared/types/session.js +28 -22
- package/dist/shared/types/workflow.js +1 -0
- package/dist/shared/validation/artifact-check.js +3 -3
- package/dist/shared/validation/artifact-contract.js +1 -1
- package/dist/shared/validation/artifact-registry.js +16 -0
- package/dist-frontend/assets/index-DDmygnV6.css +32 -0
- package/dist-frontend/assets/{index-VW9tYPP5.js → index-nAV6toi8.js} +47 -47
- package/dist-frontend/index.html +2 -2
- package/package.json +1 -1
- package/scripts/claude-plugins/vcm-lsp-bridge/.claude-plugin/plugin.json +21 -6
- package/scripts/{ccr-api-key-helper.mjs → codex-bridge-api-key-helper.mjs} +1 -1
- package/scripts/harness-tools/vcm-artifact +1 -2
- package/scripts/harness-tools/vcm-bash-guard +1 -1
- package/dist/backend/adapters/ccr-gateway-adapter.js +0 -172
- package/dist-frontend/assets/index-B0d4Z6ny.css +0 -32
|
@@ -41,7 +41,7 @@ superseded decisions, obsolete ledger items, resolved findings, prior-round
|
|
|
41
41
|
notes, stale risks, or outdated implementation guidance.
|
|
42
42
|
|
|
43
43
|
Before any other architecture-plan analysis, reconcile the Scaffold Manifest
|
|
44
|
-
ledger against the committed scaffold (\`.ai/tools/check-scaffold-ledger\`
|
|
44
|
+
ledger against the committed scaffold (\`.ai/tools/check-scaffold-ledger --mode scaffold\`
|
|
45
45
|
automates it). Run this on every review round, including revision rounds:
|
|
46
46
|
|
|
47
47
|
- Extract the ledger ID set from \`architecture-plan.md\` and the \`VCM:CODE\` ID
|
|
@@ -127,6 +127,14 @@ of verifying only the cited instances. A claimed-complete enumeration with
|
|
|
127
127
|
neither a recorded command nor a judgment-derived basis, or one that fails
|
|
128
128
|
reconstruction, is unsupported by code evidence and is \`request_changes\`.
|
|
129
129
|
|
|
130
|
+
When a claimed semantic class spans an accessor, backing field, trait
|
|
131
|
+
declaration, implementation method, wrapper, or alias, verify that Architect
|
|
132
|
+
queried every relevant symbol separately. One symbol's reference result cannot
|
|
133
|
+
prove the class complete. If Architect used bounded source fallback, verify the
|
|
134
|
+
evidence records the correct prior LSP operation and its missing relationship,
|
|
135
|
+
limits candidate search to the identified owning file or module, and
|
|
136
|
+
semantically verifies every candidate; text matches alone are not evidence.
|
|
137
|
+
|
|
130
138
|
Run a backward-impact pass over the plan:
|
|
131
139
|
|
|
132
140
|
- For every existing code site named by the Module/File Plan or Scaffold
|
|
@@ -249,15 +257,22 @@ Read \`.claude/agents/coder.md\`, \`.claude/agents/tester.md\`,
|
|
|
249
257
|
\`.ai/vcm/handoffs/test-report.md\`, the current validation-adequacy Gate report,
|
|
250
258
|
and \`docs/CODING_STANDARDS.md\`; use the architect definition to understand
|
|
251
259
|
implementation responsibility boundaries. Code-diff runs only after Tester
|
|
252
|
-
validation and the current validation-adequacy disposition.
|
|
253
|
-
|
|
260
|
+
validation and the current validation-adequacy disposition. VCM excludes
|
|
261
|
+
\`[VCM Harness]\` commits from the review input. Do not inspect, analyze, cite,
|
|
262
|
+
or report findings from those commits. Review every commit named by VCM and
|
|
263
|
+
nothing else.
|
|
254
264
|
|
|
255
265
|
Use every code source and evidence artifact named in the VCM prompt. A source
|
|
256
|
-
chain means the
|
|
257
|
-
commits; review the complete
|
|
266
|
+
chain means the named commits contain the original implementation and later
|
|
267
|
+
corrective commits; review the complete named set against the combined evidence. Plans,
|
|
258
268
|
completion reports, existing code, comments, and tests are evidence, not
|
|
259
269
|
authority. Determine whether the committed implementation is actually correct.
|
|
260
270
|
|
|
271
|
+
Treat every production and test hunk introduced by \`architect-debug\` or
|
|
272
|
+
\`architect-diagnosis\` as fresh code requiring independent review. Do not reduce
|
|
273
|
+
review to confirming that the reported symptom disappeared or that the recorded
|
|
274
|
+
root cause was addressed; apply the complete code-diff checks to every repair.
|
|
275
|
+
|
|
261
276
|
Before deciding:
|
|
262
277
|
|
|
263
278
|
- Inspect every changed file and diff hunk. Read the complete implementation of
|
|
@@ -267,7 +282,7 @@ Before deciding:
|
|
|
267
282
|
contract changes, read its project-owned callers, consumers, readers,
|
|
268
283
|
writers, and adjacent completion, failure, cancellation, retry, recovery, and
|
|
269
284
|
cleanup paths.
|
|
270
|
-
- Keep this reading bounded to behavior affected by the named
|
|
285
|
+
- Keep this reading bounded to behavior affected by the named commits. Do
|
|
271
286
|
not expand review to unrelated code, the whole task, whole branch, or PR.
|
|
272
287
|
- Derive applicable boundary and failure cases from the actual changed behavior.
|
|
273
288
|
Do not satisfy review by repeating a generic checklist.
|
|
@@ -583,6 +598,7 @@ from pathlib import Path
|
|
|
583
598
|
|
|
584
599
|
GATES = ("architecture-plan", "validation-adequacy", "code-diff")
|
|
585
600
|
CODE_DIFF_SOURCES = ("coder", "architect-debug", "architect-diagnosis")
|
|
601
|
+
HARNESS_COMMIT_PREFIX = "[VCM Harness] "
|
|
586
602
|
LATEST_REPORTS = {
|
|
587
603
|
"architecture-plan": ".ai/vcm/gate-reviews/architecture-plan-review.md",
|
|
588
604
|
"validation-adequacy": ".ai/vcm/gate-reviews/validation-adequacy-review.md",
|
|
@@ -735,6 +751,12 @@ def code_diff_range(root: Path, gate_record: dict):
|
|
|
735
751
|
and is_ancestor(root, gate_record["baseCommit"], head)
|
|
736
752
|
):
|
|
737
753
|
base = gate_record["baseCommit"]
|
|
754
|
+
elif (
|
|
755
|
+
gate_record.get("status") == "failed"
|
|
756
|
+
and gate_record.get("baseCommit")
|
|
757
|
+
and is_ancestor(root, gate_record["baseCommit"], head)
|
|
758
|
+
):
|
|
759
|
+
base = gate_record["baseCommit"]
|
|
738
760
|
elif (
|
|
739
761
|
gate_record.get("status") == "completed"
|
|
740
762
|
and gate_record.get("decision") == "approve"
|
|
@@ -742,6 +764,12 @@ def code_diff_range(root: Path, gate_record: dict):
|
|
|
742
764
|
and is_ancestor(root, gate_record["headCommit"], head)
|
|
743
765
|
):
|
|
744
766
|
base = gate_record["headCommit"]
|
|
767
|
+
elif (
|
|
768
|
+
gate_record.get("status") == "not_required"
|
|
769
|
+
and gate_record.get("headCommit")
|
|
770
|
+
and is_ancestor(root, gate_record["headCommit"], head)
|
|
771
|
+
):
|
|
772
|
+
base = gate_record["headCommit"]
|
|
745
773
|
else:
|
|
746
774
|
base = os.environ.get("VCM_BASE_COMMIT", "").strip()
|
|
747
775
|
if not base or not is_ancestor(root, base, head):
|
|
@@ -787,7 +815,43 @@ def source_artifacts(gate: str, sources: list[str] | None) -> list[str]:
|
|
|
787
815
|
]))
|
|
788
816
|
|
|
789
817
|
|
|
790
|
-
def
|
|
818
|
+
def reviewable_code_diff(root: Path, base: str, head: str) -> dict | None:
|
|
819
|
+
all_commits = command_text(root, ["git", "log", "--oneline", "--reverse", f"{base}..{head}"]).splitlines()
|
|
820
|
+
if not all_commits:
|
|
821
|
+
return None
|
|
822
|
+
commits = []
|
|
823
|
+
commit_shas = []
|
|
824
|
+
changed_files = []
|
|
825
|
+
diff_stats = []
|
|
826
|
+
patches = []
|
|
827
|
+
for line in all_commits:
|
|
828
|
+
_, separator, subject = line.partition(" ")
|
|
829
|
+
if separator and subject.startswith(HARNESS_COMMIT_PREFIX):
|
|
830
|
+
continue
|
|
831
|
+
commit_sha = line.split(maxsplit=1)[0]
|
|
832
|
+
commits.append(line)
|
|
833
|
+
commit_shas.append(commit_sha)
|
|
834
|
+
for changed_file in command_text(root, ["git", "show", "--format=", "--name-only", "--find-renames", commit_sha]).splitlines():
|
|
835
|
+
if changed_file and changed_file not in changed_files:
|
|
836
|
+
changed_files.append(changed_file)
|
|
837
|
+
diff_stat = command_text(root, ["git", "show", "--format=", "--stat", "--find-renames", commit_sha])
|
|
838
|
+
if diff_stat:
|
|
839
|
+
diff_stats.append(diff_stat)
|
|
840
|
+
patch = command_output(root, ["git", "show", "--format=", "--binary", "--find-renames", commit_sha])
|
|
841
|
+
if patch:
|
|
842
|
+
patches.append(patch)
|
|
843
|
+
return {
|
|
844
|
+
"baseCommit": base,
|
|
845
|
+
"headCommit": head,
|
|
846
|
+
"commits": commits,
|
|
847
|
+
"commitShas": commit_shas,
|
|
848
|
+
"changedFiles": changed_files,
|
|
849
|
+
"diffStat": "\\n".join(diff_stats),
|
|
850
|
+
"diffHash": hashlib.sha256(b"\\n".join(patches)).hexdigest(),
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
def input_hash(root: Path, gate: str, sources: list[str] | None = None, gate_record=None, code_diff=None) -> str:
|
|
791
855
|
gate_record = gate_record or {}
|
|
792
856
|
digest = hashlib.sha256()
|
|
793
857
|
core_artifact = CORE_INPUT_ARTIFACTS.get(gate)
|
|
@@ -796,7 +860,7 @@ def input_hash(root: Path, gate: str, sources: list[str] | None = None, gate_rec
|
|
|
796
860
|
digest.update(core_artifact.encode())
|
|
797
861
|
digest.update(path.read_bytes())
|
|
798
862
|
|
|
799
|
-
common = [
|
|
863
|
+
common = [] if gate == "code-diff" else [
|
|
800
864
|
"CLAUDE.md",
|
|
801
865
|
".claude/agents/architect.md",
|
|
802
866
|
".claude/agents/coder.md",
|
|
@@ -842,13 +906,10 @@ def input_hash(root: Path, gate: str, sources: list[str] | None = None, gate_rec
|
|
|
842
906
|
digest.update(command_output(root, ["git", "hash-object", "--", relative]))
|
|
843
907
|
if gate == "code-diff":
|
|
844
908
|
digest.update(("\\n".join(sources or []) or "<missing>").encode())
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
digest.update(
|
|
848
|
-
digest.update(
|
|
849
|
-
digest.update(command_output(root, ["git", "log", "--oneline", "--reverse", f"{base}..{head}"]))
|
|
850
|
-
digest.update(command_output(root, ["git", "diff", "--name-only", "--find-renames", f"{base}..{head}"]))
|
|
851
|
-
digest.update(hashlib.sha256(command_output(root, ["git", "diff", "--binary", "--find-renames", f"{base}..{head}"])).hexdigest().encode())
|
|
909
|
+
if code_diff:
|
|
910
|
+
digest.update("\\n".join(code_diff.get("commits", [])).encode())
|
|
911
|
+
digest.update("\\n".join(code_diff.get("changedFiles", [])).encode())
|
|
912
|
+
digest.update(code_diff.get("diffHash", "").encode())
|
|
852
913
|
return digest.hexdigest()
|
|
853
914
|
|
|
854
915
|
|
|
@@ -864,7 +925,7 @@ def core_input_status(root: Path, gate: str) -> tuple[str, str] | None:
|
|
|
864
925
|
return (core_artifact, "ready")
|
|
865
926
|
|
|
866
927
|
|
|
867
|
-
def code_diff_prerequisite_error(root: Path, index: dict) -> str | None:
|
|
928
|
+
def code_diff_prerequisite_error(root: Path, index: dict, check_validation_gate: bool = True) -> str | None:
|
|
868
929
|
report_path = root / ".ai/vcm/handoffs/test-report.md"
|
|
869
930
|
try:
|
|
870
931
|
report = report_path.read_text()
|
|
@@ -876,6 +937,9 @@ def code_diff_prerequisite_error(root: Path, index: dict) -> str | None:
|
|
|
876
937
|
if result.group(1).lower() == "incomplete":
|
|
877
938
|
return "code-diff requires completed Tester validation. Test Result is incomplete."
|
|
878
939
|
|
|
940
|
+
if not check_validation_gate:
|
|
941
|
+
return None
|
|
942
|
+
|
|
879
943
|
validation = index.get("gates", {}).get("validation-adequacy", {})
|
|
880
944
|
if not isinstance(validation, dict) or not validation.get("required", False):
|
|
881
945
|
return None
|
|
@@ -894,6 +958,35 @@ def request_id(gate: str) -> str:
|
|
|
894
958
|
return f"{stamp}-{gate}-{uuid.uuid4().hex[:8]}"
|
|
895
959
|
|
|
896
960
|
|
|
961
|
+
def record_code_diff_start_failure(index_path: Path, index: dict, gate: str, reason: str, code_diff=None) -> None:
|
|
962
|
+
code_diff = code_diff or {}
|
|
963
|
+
gate_record = index["gates"].setdefault(gate, {})
|
|
964
|
+
gate_record.update({
|
|
965
|
+
"required": True,
|
|
966
|
+
"status": "failed",
|
|
967
|
+
"decision": None,
|
|
968
|
+
"error": reason,
|
|
969
|
+
"exceptionReason": None,
|
|
970
|
+
"requestId": None,
|
|
971
|
+
"requestPath": None,
|
|
972
|
+
"inputHash": None,
|
|
973
|
+
"baseCommit": code_diff.get("baseCommit"),
|
|
974
|
+
"headCommit": code_diff.get("headCommit"),
|
|
975
|
+
"commits": code_diff.get("commits"),
|
|
976
|
+
"changedFiles": code_diff.get("changedFiles"),
|
|
977
|
+
"diffStat": code_diff.get("diffStat"),
|
|
978
|
+
"requestedAt": None,
|
|
979
|
+
"startedAt": None,
|
|
980
|
+
"completedAt": now_iso(),
|
|
981
|
+
"callbackStatus": "not_sent",
|
|
982
|
+
"callbackError": None,
|
|
983
|
+
"updatedAt": now_iso(),
|
|
984
|
+
})
|
|
985
|
+
if index.get("activeGate") == gate:
|
|
986
|
+
index["activeGate"] = None
|
|
987
|
+
write_json(index_path, index)
|
|
988
|
+
|
|
989
|
+
|
|
897
990
|
def local_request(gate: str, source: str | None) -> int:
|
|
898
991
|
root = root_dir()
|
|
899
992
|
index_path = root / ".ai/vcm/gate-reviews/index.json"
|
|
@@ -986,14 +1079,23 @@ def local_request(gate: str, source: str | None) -> int:
|
|
|
986
1079
|
return 0
|
|
987
1080
|
|
|
988
1081
|
if gate == "code-diff":
|
|
989
|
-
|
|
990
|
-
if
|
|
1082
|
+
evidence_error = code_diff_prerequisite_error(root, index, False)
|
|
1083
|
+
if evidence_error:
|
|
1084
|
+
record_code_diff_start_failure(index_path, index, gate, evidence_error)
|
|
1085
|
+
print_result("failed_to_start", gate=gate, reason=evidence_error)
|
|
1086
|
+
return 2
|
|
1087
|
+
|
|
1088
|
+
gate_record = index["gates"].get(gate, {})
|
|
1089
|
+
code_diff = {}
|
|
1090
|
+
if gate == "code-diff":
|
|
1091
|
+
base, head = code_diff_range(root, gate_record if isinstance(gate_record, dict) else {})
|
|
1092
|
+
if not base or not head or base == head:
|
|
991
1093
|
gate_record = index["gates"].setdefault(gate, {})
|
|
992
1094
|
gate_record.update({
|
|
993
1095
|
"required": True,
|
|
994
|
-
"status": "
|
|
1096
|
+
"status": "not_required",
|
|
995
1097
|
"decision": None,
|
|
996
|
-
"error":
|
|
1098
|
+
"error": None,
|
|
997
1099
|
"exceptionReason": None,
|
|
998
1100
|
"requestId": None,
|
|
999
1101
|
"requestPath": None,
|
|
@@ -1005,7 +1107,7 @@ def local_request(gate: str, source: str | None) -> int:
|
|
|
1005
1107
|
"diffStat": None,
|
|
1006
1108
|
"requestedAt": None,
|
|
1007
1109
|
"startedAt": None,
|
|
1008
|
-
"completedAt":
|
|
1110
|
+
"completedAt": None,
|
|
1009
1111
|
"callbackStatus": "not_sent",
|
|
1010
1112
|
"callbackError": None,
|
|
1011
1113
|
"updatedAt": now_iso(),
|
|
@@ -1013,14 +1115,13 @@ def local_request(gate: str, source: str | None) -> int:
|
|
|
1013
1115
|
if index.get("activeGate") == gate:
|
|
1014
1116
|
index["activeGate"] = None
|
|
1015
1117
|
write_json(index_path, index)
|
|
1016
|
-
print_result("
|
|
1017
|
-
return
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
if not base or not head or base == head:
|
|
1118
|
+
print_result("not_required", gate=gate, message="No new commits to review.")
|
|
1119
|
+
return 0
|
|
1120
|
+
code_diff = reviewable_code_diff(root, base, head)
|
|
1121
|
+
if code_diff is None:
|
|
1122
|
+
print_result("not_required", gate=gate, message="No new commits to review.")
|
|
1123
|
+
return 0
|
|
1124
|
+
if not code_diff["commits"]:
|
|
1024
1125
|
gate_record = index["gates"].setdefault(gate, {})
|
|
1025
1126
|
gate_record.update({
|
|
1026
1127
|
"required": True,
|
|
@@ -1031,14 +1132,14 @@ def local_request(gate: str, source: str | None) -> int:
|
|
|
1031
1132
|
"requestId": None,
|
|
1032
1133
|
"requestPath": None,
|
|
1033
1134
|
"inputHash": None,
|
|
1034
|
-
"baseCommit":
|
|
1035
|
-
"headCommit":
|
|
1036
|
-
"commits":
|
|
1037
|
-
"changedFiles":
|
|
1038
|
-
"diffStat":
|
|
1135
|
+
"baseCommit": base,
|
|
1136
|
+
"headCommit": head,
|
|
1137
|
+
"commits": [],
|
|
1138
|
+
"changedFiles": [],
|
|
1139
|
+
"diffStat": "",
|
|
1039
1140
|
"requestedAt": None,
|
|
1040
1141
|
"startedAt": None,
|
|
1041
|
-
"completedAt":
|
|
1142
|
+
"completedAt": now_iso(),
|
|
1042
1143
|
"callbackStatus": "not_sent",
|
|
1043
1144
|
"callbackError": None,
|
|
1044
1145
|
"updatedAt": now_iso(),
|
|
@@ -1046,23 +1147,17 @@ def local_request(gate: str, source: str | None) -> int:
|
|
|
1046
1147
|
if index.get("activeGate") == gate:
|
|
1047
1148
|
index["activeGate"] = None
|
|
1048
1149
|
write_json(index_path, index)
|
|
1049
|
-
print_result("not_required", gate=gate, message="No
|
|
1050
|
-
return 0
|
|
1051
|
-
commit_lines = command_text(root, ["git", "log", "--oneline", "--reverse", f"{base}..{head}"]).splitlines()
|
|
1052
|
-
changed_files = command_text(root, ["git", "diff", "--name-only", "--find-renames", f"{base}..{head}"]).splitlines()
|
|
1053
|
-
if not commit_lines:
|
|
1054
|
-
print_result("not_required", gate=gate, message="No new commits to review.")
|
|
1150
|
+
print_result("not_required", gate=gate, message="No non-Harness commits to review.")
|
|
1055
1151
|
return 0
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
"
|
|
1061
|
-
|
|
1062
|
-
}
|
|
1152
|
+
|
|
1153
|
+
prerequisite_error = code_diff_prerequisite_error(root, index)
|
|
1154
|
+
if prerequisite_error:
|
|
1155
|
+
record_code_diff_start_failure(index_path, index, gate, prerequisite_error, code_diff)
|
|
1156
|
+
print_result("failed_to_start", gate=gate, reason=prerequisite_error)
|
|
1157
|
+
return 2
|
|
1063
1158
|
|
|
1064
1159
|
sources = code_diff_sources(gate_record, source, code_diff) if gate == "code-diff" else None
|
|
1065
|
-
current_hash = input_hash(root, gate, sources, gate_record if isinstance(gate_record, dict) else {})
|
|
1160
|
+
current_hash = input_hash(root, gate, sources, gate_record if isinstance(gate_record, dict) else {}, code_diff)
|
|
1066
1161
|
if (
|
|
1067
1162
|
gate_record.get("status") == "completed"
|
|
1068
1163
|
and gate_record.get("decision") == "approve"
|
|
@@ -57,7 +57,8 @@ You are not part of the task workflow round state.
|
|
|
57
57
|
active memory blocks. Record every assigned pending feedback disposition in
|
|
58
58
|
the report. Do not edit or delete pending feedback files; VCM removes accepted
|
|
59
59
|
assignments after validating the report.
|
|
60
|
-
- Commit every applied harness change yourself before ending your turn.
|
|
60
|
+
- Commit every applied harness change yourself before ending your turn. Keep
|
|
61
|
+
Harness changes in their own commit and use subject \`[VCM Harness] <summary>\`.
|
|
61
62
|
- Do not overwrite VCM fixed managed blocks.
|
|
62
63
|
- Keep project-specific customization outside VCM managed blocks.
|
|
63
64
|
- If a fixed managed block appears wrong, draft a VCM issue instead of editing
|
|
@@ -89,18 +90,21 @@ You are not part of the task workflow round state.
|
|
|
89
90
|
- Do not keep the full content in memory when a durable document is the correct
|
|
90
91
|
source. Use a short memory reference only when the role needs that document
|
|
91
92
|
pointer across tasks.
|
|
92
|
-
-
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
- Write the complete decision set and durable-document assignments to the exact
|
|
94
|
+
\`review-result.json\` path assigned by VCM. Keep the retrospective Memory
|
|
95
|
+
Review section limited to the memory commit, result path, and assignment count.
|
|
95
96
|
- Do not record task narrative, temporary state, unverified conclusions, or
|
|
96
97
|
Harness rules in memory.
|
|
97
98
|
- Edit only the \`<VCM-memory>\` blocks in the active memory files assigned by
|
|
98
99
|
VCM. Do not change surrounding role definitions, project context, or managed
|
|
99
100
|
Harness blocks during Auto Memory Review.
|
|
100
101
|
- If the reviewed memory changes, commit only the changed active memory files
|
|
101
|
-
with commit message \`
|
|
102
|
+
with commit message \`[VCM Harness] Update VCM memory\` before ending the turn. If
|
|
102
103
|
memory is unchanged, do not create a commit. VCM records the committed result,
|
|
103
104
|
diff, and review history; it does not apply or commit the memory for you.
|
|
105
|
+
- For \`move-to-durable-doc\`, remove the entry from memory in this review and
|
|
106
|
+
record the durable-document assignment in \`review-result.json\`. Do not edit
|
|
107
|
+
the durable document yourself and do not wait to remove the memory entry.
|
|
104
108
|
|
|
105
109
|
## Task Harness Retrospective
|
|
106
110
|
|
|
@@ -142,12 +146,10 @@ Impact: <impact>
|
|
|
142
146
|
Required action: <action or none>
|
|
143
147
|
\`\`\`
|
|
144
148
|
|
|
145
|
-
Write the complete retrospective report to
|
|
146
|
-
submit it with \`.ai/tools/vcm-artifact retrospective-report --file <candidate>
|
|
147
|
-
--path <assigned-report-path> --mode final\`.
|
|
149
|
+
Write the complete retrospective report directly to the assigned Result Path.
|
|
148
150
|
|
|
149
|
-
Do not edit or delete pending feedback files. VCM
|
|
150
|
-
disposition and removes the assigned files
|
|
151
|
+
Do not edit or delete pending feedback files. VCM reads the report after the
|
|
152
|
+
turn, validates every assigned disposition, and removes the assigned files.
|
|
151
153
|
|
|
152
154
|
For each finding, decide whether it is:
|
|
153
155
|
|
|
@@ -183,6 +185,9 @@ Use this report structure:
|
|
|
183
185
|
|
|
184
186
|
<!-- Include Memory Review only when VCM assigns Auto Memory Review. -->
|
|
185
187
|
## Memory Review
|
|
188
|
+
Memory commit: <full commit or none>
|
|
189
|
+
Review result: <assigned review-result.json path>
|
|
190
|
+
Durable document assignments: <count>
|
|
186
191
|
\`\`\`
|
|
187
192
|
|
|
188
193
|
## VCM Feedback
|
|
@@ -196,6 +201,16 @@ Issue drafts must include title, problem, reproduction, expected behavior,
|
|
|
196
201
|
actual behavior, VCM version when known, affected harness/UI area, impact, and a
|
|
197
202
|
suggested fix if known.
|
|
198
203
|
|
|
204
|
+
Before adding a later finding to an issue used in the current conversation,
|
|
205
|
+
check that issue's current state.
|
|
206
|
+
|
|
207
|
+
Do not add actionable work to a closed issue. Create a new issue and reference
|
|
208
|
+
the closed issue instead.
|
|
209
|
+
|
|
210
|
+
Add a comment only when the finding updates or corrects the same work. If the
|
|
211
|
+
finding can be implemented, tested, and closed independently, create a separate
|
|
212
|
+
issue and reference the related issue.
|
|
213
|
+
|
|
199
214
|
Do not submit issues yourself unless the harness owner gives explicit
|
|
200
215
|
in-session authorization. Do not include private source code, secrets, private
|
|
201
216
|
logs, or unnecessary repository details. Summarize private context instead of
|
|
@@ -23,6 +23,13 @@ ${renderRoleMemoryRules("project-manager")}
|
|
|
23
23
|
- Exclude irrelevant implementation detail, but retain the technical facts needed to explain the cause, evidence, impact, and unresolved state. Plain language means translating technical detail, not deleting it.
|
|
24
24
|
- Do not oversimplify findings. Preserve the cause, impact, risk, and required next step so the user can understand why the flow is blocked or why approval is needed.
|
|
25
25
|
|
|
26
|
+
### User Question Boundary
|
|
27
|
+
|
|
28
|
+
- Whenever PM asks the user any question, use \`vcm-ask-user\` with the exact question before asking it.
|
|
29
|
+
- After asking, end the turn. Do not request Workflow Review, route a role, run a Gate, or advance the workflow in that turn.
|
|
30
|
+
- Resume only after a new direct user message. Request a fresh Workflow Review before the next role dispatch.
|
|
31
|
+
- PM may defer a question by not asking it. Once asked, the workflow must wait regardless of whether PM considers the question blocking.
|
|
32
|
+
|
|
26
33
|
### Complex Problem Reporting
|
|
27
34
|
|
|
28
35
|
When reporting a blocker, failed validation, Gate Review finding, Architecture Diagnosis result, unresolved risk, or workflow pause:
|
|
@@ -46,7 +53,6 @@ PM Managed Mode applies only when the user explicitly asks to complete the curre
|
|
|
46
53
|
- PM must pause and ask the user only when the task cannot proceed without user intent or real-world authorization: unclear or conflicting requested outcome, required account/secret/test environment/data access, real cost, production permission, sensitive data access, destructive or irreversible real-world action, durable-doc conflict requiring user choice, or a required user-approved exception.
|
|
47
54
|
- Required user-approved exceptions include skipped required validation, Gate Review skip or override, skipped required docs sync, accepted unresolved task-scope risk, or weakening baseline Harness rules.
|
|
48
55
|
- PM records user approvals exactly as given. PM must not create, broaden, infer, or reuse approval.
|
|
49
|
-
- When PM asks the user, the flow must stop and wait for the user's explicit instruction before continuing.
|
|
50
56
|
|
|
51
57
|
### Task Flow Selection
|
|
52
58
|
|
|
@@ -217,13 +223,13 @@ stays paused.
|
|
|
217
223
|
|
|
218
224
|
### Docs-Only Flow
|
|
219
225
|
|
|
220
|
-
Use Docs-Only Flow when the accepted task changes
|
|
226
|
+
Use Docs-Only Flow when the accepted task changes documentation and does not require production-code, test-code, runtime-behavior, public-contract, dependency, or Harness changes.
|
|
221
227
|
|
|
222
228
|
The flow is:
|
|
223
229
|
|
|
224
|
-
\`
|
|
230
|
+
\`Assigned documentation role or roles -> PM completion\`
|
|
225
231
|
|
|
226
|
-
Architect
|
|
232
|
+
Route Architect, Coder, or Tester according to the document content and the role best able to verify it. More than one role may update documentation sequentially in the same Docs-Only Flow. Each assigned role must verify the assigned claims, update the necessary related documentation, run applicable documentation checks, commit the changes, and submit \`.ai/vcm/handoffs/docs-update-report.md\` with:
|
|
227
233
|
|
|
228
234
|
- \`Decision: synced\`
|
|
229
235
|
- \`Decision: unchanged\`
|
|
@@ -235,20 +241,20 @@ PM may leave this path only through the allowed branches below.
|
|
|
235
241
|
|
|
236
242
|
#### Allowed Branches
|
|
237
243
|
|
|
238
|
-
- **Documentation Revision:** If the document update or evidence is incomplete, route
|
|
244
|
+
- **Documentation Revision:** If the document update or evidence is incomplete, route the same role or another appropriate documentation role.
|
|
239
245
|
- **Code Change Required:** If the accepted outcome requires implementation changes, enter Code-Change Flow at Architect planning.
|
|
240
|
-
- **Validation
|
|
246
|
+
- **Validation Required:** If the accepted outcome requires test or validation work rather than documentation alone, enter Validation-Only Flow at Tester.
|
|
241
247
|
- **User Decision:** If conflicting durable requirements require user intent, pause and ask the user.
|
|
242
248
|
|
|
243
249
|
#### Completion
|
|
244
250
|
|
|
245
|
-
The flow completes when the accepted \`.ai/vcm/handoffs/docs-
|
|
251
|
+
The flow completes when the latest assigned role submits an accepted \`.ai/vcm/handoffs/docs-update-report.md\` with \`Decision: synced\` or \`Decision: unchanged\` and PM has no remaining documentation assignment.
|
|
246
252
|
|
|
247
253
|
Docs-Only Flow does not run architecture-plan Gate Review, code-diff Gate Review, Tester validation, validation-adequacy Gate Review, separate post-validation docs sync, or Final Acceptance.
|
|
248
254
|
|
|
249
255
|
### Validation-Only Flow
|
|
250
256
|
|
|
251
|
-
Use Validation-Only Flow when the accepted task requires validation, test changes, test fixtures, test-only helpers
|
|
257
|
+
Use Validation-Only Flow when the accepted task requires validation, test changes, test fixtures, or test-only helpers without production-code, runtime-behavior, public-contract, dependency, or system-architecture changes. A documentation-only change to \`docs/TESTING.md\` may use Docs-Only Flow.
|
|
252
258
|
|
|
253
259
|
The flow is:
|
|
254
260
|
|
|
@@ -322,7 +328,7 @@ PM may lightly rewrite the user's words to:
|
|
|
322
328
|
- Do not allow requested work to be deferred, converted into follow-up scope, reduced, or returned to the user because of workload, session length, context size, task size, predicted difficulty, or role preference.
|
|
323
329
|
- PM must not route Coder concerns to Architect before Coder completes the assigned scaffold and reports objective implementation evidence.
|
|
324
330
|
- Coder feedback that stops before the full sweep of assigned items is incomplete work, not a valid failure or architecture signal.
|
|
325
|
-
- Before acting on any Coder decision,
|
|
331
|
+
- Before acting on any Coder decision, run \`.ai/tools/check-scaffold-ledger --mode completion --completion .ai/vcm/handoffs/coder-completion.md\`. It must pass; this verifies that every Scaffold Manifest item appears exactly once in Scaffold Completion, each disposition matches the tree marker state, and the Decision matches the dispositions.
|
|
326
332
|
- Return any missing, duplicate, unswept, marker-inconsistent, or decision-inconsistent result to Coder as incomplete work regardless of the reported Decision.
|
|
327
333
|
- If Coder returns questions, concerns, predictions, architecture doubts, or validation worries before completing the assigned implementation, route Coder back to finish the work.
|
|
328
334
|
- PM must not forward Coder critique of the architecture plan, scaffold, module boundaries, public contracts, or validation strategy to Architect before Coder submits \`coder-completion.md\` with compile/typecheck/L0/L1 evidence.
|
|
@@ -334,7 +340,7 @@ PM may lightly rewrite the user's words to:
|
|
|
334
340
|
- In normal code-change flow, track the confirmed architecture brief, architecture plan, test report, docs-sync report, required Gate Review results, known-issues disposition when present, and final acceptance report.
|
|
335
341
|
- In an Architect Debug Branch or Architecture Diagnosis Branch, track the parent flow, resume point, Architect result, test report, and required Gate Review results. Do not require a branch-level final acceptance report.
|
|
336
342
|
- In an Architect Debug Flow or Architecture Diagnosis Flow that produces code changes, track the Architect result, test report, required Gate Review results, docs-sync report, and final acceptance report.
|
|
337
|
-
- In Docs-Only Flow, complete only from an accepted \`docs-
|
|
343
|
+
- In Docs-Only Flow, complete only from an accepted \`docs-update-report.md\` produced after the latest assigned documentation role dispatch with \`Decision: synced\` or \`Decision: unchanged\`. In Validation-Only Flow, complete only from a complete \`test-report.md\` after the validation-adequacy Gate finishes successfully.
|
|
338
344
|
- A Tester \`Test Result: incomplete\` is continuation state, not failure evidence. Route Tester again and do not run validation-adequacy Gate Review or Final Acceptance from it.
|
|
339
345
|
- The Architect does not begin planning until \`architecture-brief.md\` is confirmed (this happens inside the same Architect Interview-and-planning turn, not a separate PM route). Advance to the next gate only when the required role artifact/result is complete and PM routing rules allow that gate.
|
|
340
346
|
- If a required artifact is missing, stale, blocked, or asks for a decision, route the issue to the responsible role or user.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export function renderResolveDurableDocAssignmentTool() {
|
|
2
|
+
return `#!/usr/bin/env python3
|
|
3
|
+
import argparse
|
|
4
|
+
import json
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
import urllib.error
|
|
8
|
+
import urllib.request
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def emit(status, message=None):
|
|
12
|
+
payload = {"status": status}
|
|
13
|
+
if message:
|
|
14
|
+
payload["message"] = message
|
|
15
|
+
print(json.dumps(payload, ensure_ascii=False))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def main():
|
|
19
|
+
parser = argparse.ArgumentParser(description="Assign a VCM durable-document update to a workflow role.")
|
|
20
|
+
parser.add_argument("--assignment", required=True)
|
|
21
|
+
parser.add_argument("--owner", required=True, choices=["architect", "coder", "tester"])
|
|
22
|
+
args = parser.parse_args()
|
|
23
|
+
|
|
24
|
+
if os.environ.get("VCM_ROLE") != "project-manager":
|
|
25
|
+
emit("rejected", "Only project-manager may resolve a durable-document owner.")
|
|
26
|
+
return 2
|
|
27
|
+
|
|
28
|
+
api_url = os.environ.get("VCM_API_URL", "").rstrip("/")
|
|
29
|
+
task_slug = os.environ.get("VCM_TASK_SLUG", "").strip()
|
|
30
|
+
if not api_url or not task_slug:
|
|
31
|
+
emit("rejected", "VCM_API_URL or VCM_TASK_SLUG is unavailable.")
|
|
32
|
+
return 2
|
|
33
|
+
|
|
34
|
+
request = urllib.request.Request(
|
|
35
|
+
api_url + "/api/projects/harness/memory/assignments/owner",
|
|
36
|
+
data=json.dumps({
|
|
37
|
+
"taskSlug": task_slug,
|
|
38
|
+
"assignmentId": args.assignment,
|
|
39
|
+
"owner": args.owner,
|
|
40
|
+
}).encode("utf-8"),
|
|
41
|
+
headers={"content-type": "application/json"},
|
|
42
|
+
method="POST",
|
|
43
|
+
)
|
|
44
|
+
try:
|
|
45
|
+
with urllib.request.urlopen(request, timeout=5):
|
|
46
|
+
pass
|
|
47
|
+
emit("accepted")
|
|
48
|
+
return 0
|
|
49
|
+
except urllib.error.HTTPError as error:
|
|
50
|
+
detail = error.read().decode("utf-8", errors="replace")
|
|
51
|
+
emit("rejected", f"VCM rejected the owner: HTTP {error.code} {detail}")
|
|
52
|
+
except (OSError, ValueError, urllib.error.URLError) as error:
|
|
53
|
+
emit("failed", f"VCM could not record the owner: {error}")
|
|
54
|
+
return 2
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
if __name__ == "__main__":
|
|
58
|
+
sys.exit(main())
|
|
59
|
+
`;
|
|
60
|
+
}
|
|
@@ -10,6 +10,7 @@ ${renderRoleMemoryRules("tester")}
|
|
|
10
10
|
- Own independent validation, tester-owned test design, test implementation, test adequacy, \`docs/TESTING.md\`, and final validation confidence.
|
|
11
11
|
- Read production code only to understand public behavior, test seams, fixtures, and coverage gaps.
|
|
12
12
|
- Do not edit production code or decide architecture. Diagnose and repair only PM-routed defects confined to Tester-owned tests, fixtures, test-only helpers, and \`docs/TESTING.md\`; otherwise report validation evidence without proposing a fix.
|
|
13
|
+
- In a PM-routed Docs-Only Flow, update the assigned documentation and related documentation needed for consistency without changing production code or tests.
|
|
13
14
|
|
|
14
15
|
### Inputs
|
|
15
16
|
|
|
@@ -35,6 +36,18 @@ ${renderRoleMemoryRules("tester")}
|
|
|
35
36
|
- Apply \`docs/CODING_STANDARDS.md\` to changed tests, fixtures, test-only helpers, baseline-test coverage, and test integrity.
|
|
36
37
|
- Before final validation, perform a full cache cleanup, then rerun validation from a clean state.
|
|
37
38
|
- Do not use validation results produced before full cache cleanup as final acceptance evidence.
|
|
39
|
+
|
|
40
|
+
### Docs-Only Flow
|
|
41
|
+
|
|
42
|
+
- For a \`[VCM Durable Documentation Assignment]\`, verify and update the assigned
|
|
43
|
+
durable document and directly related documentation, run applicable
|
|
44
|
+
documentation checks, commit the result, and submit \`docs-update-report.md\`
|
|
45
|
+
with the exact assigned Assignment ID. This backend assignment does not start
|
|
46
|
+
Docs-Only Flow.
|
|
47
|
+
|
|
48
|
+
- Verify the assigned documentation against current project evidence, update the required documentation, run applicable documentation checks, and commit the changes.
|
|
49
|
+
- Submit \`.ai/vcm/handoffs/docs-update-report.md\` through \`vcm-artifact\` with the decision, changed and reviewed documents, evidence, checks, commit, and remaining documentation issues.
|
|
50
|
+
- Do not submit \`test-report.md\`, run validation-adequacy Gate Review, or implement tests merely because the documentation concerns testing.
|
|
38
51
|
- Record failed commands, observed behavior, expected behavior, reproduction steps, and skipped checks. Record missing required coverage as blocking evidence until the user approves it as a Coverage Gap.
|
|
39
52
|
- Report failures as validation evidence: expected behavior, actual behavior, reproduction, affected path, failed command or log, and risk.
|
|
40
53
|
- Do not propose implementation fixes, architecture changes, Replan, or ownership changes.
|