vibe-coding-master 0.8.6 → 0.8.7
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
CHANGED
|
@@ -595,11 +595,17 @@ with the exact assigned `--path` and Assignment ID. Reports are isolated under
|
|
|
595
595
|
The reported commit must modify the target document within the assignment's
|
|
596
596
|
original commit range; unrelated later commits do not invalidate it. Existing
|
|
597
597
|
correct documentation can be reported as `unchanged` without a new commit.
|
|
598
|
+
For `synced`, the entire `Commit` section is one bare lowercase hexadecimal
|
|
599
|
+
hash (7-40 characters), without Markdown or explanatory text. The template,
|
|
600
|
+
artifact submission, and assignment completion use the same format contract.
|
|
598
601
|
|
|
599
602
|
Assignments run one at a time. A failed assignment does not block later items.
|
|
600
603
|
After the remaining items finish, unresolved failures are reported in Harness
|
|
601
604
|
Studio with their causes and individual Retry buttons. Retry preserves earlier
|
|
602
605
|
committed work and the original baseline, including after a backend restart.
|
|
606
|
+
An old assignment whose baseline was already overwritten is not automatically
|
|
607
|
+
rebased; verify the current document and use `unchanged` when it already preserves
|
|
608
|
+
the assigned content. Errors identify the reported commit and recorded range.
|
|
603
609
|
Migration content and review snapshots remain in the task-local run directory;
|
|
604
610
|
failures do not automatically restore removed memory. Turning Auto Memory off
|
|
605
611
|
does not discard or cancel already-applied document migrations.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { checkMarkdownArtifact, readArtifactSectionValue } from "../../shared/validation/artifact-check.js";
|
|
3
|
+
import { checkMarkdownArtifact, readArtifactSectionContent, readArtifactSectionValue } from "../../shared/validation/artifact-check.js";
|
|
4
|
+
import { DOCS_UPDATE_COMMIT_RULE } from "../../shared/validation/artifact-contract.js";
|
|
4
5
|
import { resolveRepoPath } from "../adapters/filesystem.js";
|
|
5
6
|
import { VcmError } from "../errors.js";
|
|
6
7
|
import { submitTerminalInput } from "../runtime/terminal-submit.js";
|
|
@@ -780,24 +781,34 @@ export function createAutoMemoryService(deps) {
|
|
|
780
781
|
return currentHead;
|
|
781
782
|
}
|
|
782
783
|
async function validateDurableDocCommit(taskRepoRoot, assignment, reportContent, currentHead) {
|
|
783
|
-
|
|
784
|
-
|
|
784
|
+
const reportedCommit = readArtifactSectionContent(reportContent, "Commit");
|
|
785
|
+
let commit;
|
|
786
|
+
try {
|
|
787
|
+
commit = (await deps.git.getCommitInfo(taskRepoRoot, reportedCommit)).sha;
|
|
785
788
|
}
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
throw new Error(`
|
|
789
|
+
catch (error) {
|
|
790
|
+
const detail = error instanceof VcmError && error.hint ? `${errorMessage(error)} ${error.hint}` : errorMessage(error);
|
|
791
|
+
throw new Error(`Commit ${reportedCommit} could not be resolved to a unique Git commit: ${detail}`);
|
|
792
|
+
}
|
|
793
|
+
const existingContentHint = `If ${assignment.targetPath} already preserves the assigned content, report unchanged with verification evidence; do not create a redundant commit.`;
|
|
794
|
+
if (!assignment.baseCommit) {
|
|
795
|
+
throw new Error(`Assignment ${assignment.id} has no recorded commit baseline; cannot validate Commit ${commit}. ${existingContentHint}`);
|
|
796
|
+
}
|
|
797
|
+
if (currentHead === assignment.baseCommit) {
|
|
798
|
+
throw new Error(`No commits follow assignment baseline ${assignment.baseCommit} (HEAD is the same commit); received Commit ${commit}. The document may already have been committed before this baseline. ${existingContentHint}`);
|
|
789
799
|
}
|
|
790
|
-
const reportedCommit = readArtifactSectionValue(reportContent, "Commit")?.trim();
|
|
791
800
|
const commits = await deps.git.getCommitList(taskRepoRoot, `${assignment.baseCommit}..${currentHead}`);
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
throw new Error(`Commit must uniquely identify a documentation commit in ${assignment.baseCommit}..${currentHead}; received ${reportedCommit || "empty"}`);
|
|
801
|
+
if (!commits.some((candidate) => candidate.sha === commit)) {
|
|
802
|
+
throw new Error(`Commit ${commit} exists but is outside assignment range ${assignment.baseCommit}..${currentHead}. ${existingContentHint}`);
|
|
795
803
|
}
|
|
796
|
-
const commit = matches[0].sha;
|
|
797
804
|
const commitPaths = await deps.git.getChangedPaths(taskRepoRoot, `${commit}^`, commit);
|
|
798
805
|
if (!commitPaths.includes(assignment.targetPath)) {
|
|
799
806
|
throw new Error(`reported commit ${commit} does not modify ${assignment.targetPath}`);
|
|
800
807
|
}
|
|
808
|
+
const changedPaths = await deps.git.getChangedPaths(taskRepoRoot, assignment.baseCommit, currentHead);
|
|
809
|
+
if (!changedPaths.includes(assignment.targetPath)) {
|
|
810
|
+
throw new Error(`Commit ${commit} modified ${assignment.targetPath}, but no net change remains in ${assignment.baseCommit}..${currentHead}. Verify the current document before reporting completion.`);
|
|
811
|
+
}
|
|
801
812
|
return commit;
|
|
802
813
|
}
|
|
803
814
|
async function hashOptionalFile(taskRepoRoot, relativePath) {
|
|
@@ -1498,6 +1509,7 @@ function buildDurableDocAssignmentPrompt(taskRepoRoot, assignment) {
|
|
|
1498
1509
|
`Assigned report path: ${assignment.reportPath}`,
|
|
1499
1510
|
`Submit with .ai/tools/vcm-artifact docs-update-report --file <candidate> --path ${assignment.reportPath} --mode final`,
|
|
1500
1511
|
"Set Assignment ID to the exact ID above.",
|
|
1512
|
+
DOCS_UPDATE_COMMIT_RULE,
|
|
1501
1513
|
"For synced, record the commit that changed the target document; it need not be HEAD. If the document already preserves the content, use unchanged with evidence; do not create a redundant commit.",
|
|
1502
1514
|
...(assignment.error ? [`Previous failure: ${assignment.error}`] : []),
|
|
1503
1515
|
"End the turn after VCM accepts the report."
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ARCHITECT_DEBUG_DISPOSITIONS, ARCHITECT_DEBUG_STATUSES, ARCHITECTURE_BRIEF_STATUSES, ARCHITECTURE_DIAGNOSIS_DISPOSITIONS, ARCHITECTURE_EVIDENCE_STATUSES, ARCHITECTURE_PLAN_RESULTS, CODER_COMPLETION_DECISIONS, DOCS_REPORT_DECISIONS, DOCS_SYNC_CORRECTION_OWNERS, FINAL_ACCEPTANCE_DECISIONS, L3_ACTIONS, L3_REQUIRED_VALUES, PLANNING_PROGRESS_STATUSES, STRICT_NONE_VALUE, TEST_INFRASTRUCTURE_STATUSES, TEST_RESULTS, renderArtifactOptions } from "../../shared/validation/artifact-contract.js";
|
|
1
|
+
import { ARCHITECT_DEBUG_DISPOSITIONS, ARCHITECT_DEBUG_STATUSES, ARCHITECTURE_BRIEF_STATUSES, ARCHITECTURE_DIAGNOSIS_DISPOSITIONS, ARCHITECTURE_EVIDENCE_STATUSES, ARCHITECTURE_PLAN_RESULTS, CODER_COMPLETION_DECISIONS, DOCS_REPORT_DECISIONS, DOCS_UPDATE_COMMIT_RULE, DOCS_SYNC_CORRECTION_OWNERS, FINAL_ACCEPTANCE_DECISIONS, L3_ACTIONS, L3_REQUIRED_VALUES, PLANNING_PROGRESS_STATUSES, STRICT_NONE_VALUE, TEST_INFRASTRUCTURE_STATUSES, TEST_RESULTS, renderArtifactOptions } from "../../shared/validation/artifact-contract.js";
|
|
2
2
|
const CURRENT_HANDOFF_NOTICE = "<!-- VCM current handoff: replace this file with one complete, self-contained snapshot of the current result. Restate all still-relevant evidence; do not refer to a prior revision, route message, Session, or transcript as evidence. -->";
|
|
3
3
|
export function renderArchitectureBriefTemplate(taskSlug) {
|
|
4
4
|
return `# Architecture Brief: ${taskSlug}
|
|
@@ -534,6 +534,8 @@ export function renderDocsUpdateReportTemplate(taskSlug, assignmentId = "docs-on
|
|
|
534
534
|
|
|
535
535
|
${CURRENT_HANDOFF_NOTICE}
|
|
536
536
|
|
|
537
|
+
${DOCS_UPDATE_COMMIT_RULE}
|
|
538
|
+
|
|
537
539
|
## Summary
|
|
538
540
|
|
|
539
541
|
TBD
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ARCHITECT_DEBUG_DISPOSITIONS, ARCHITECT_DEBUG_STATUSES, ARCHITECTURE_BRIEF_STATUSES, ARCHITECTURE_DIAGNOSIS_DISPOSITIONS, ARCHITECTURE_EVIDENCE_STATUSES, ARCHITECTURE_PLAN_RESULTS, CODER_COMPLETION_DECISIONS, DOCS_REPORT_DECISIONS, DOCS_SYNC_CORRECTION_OWNERS, FINAL_ACCEPTANCE_DECISIONS, L3_ACTIONS, L3_REQUIRED_VALUES, PLANNING_PROGRESS_STATUSES, STRICT_NONE_VALUE, TEST_INFRASTRUCTURE_STATUSES, TEST_RESULTS } from "./artifact-contract.js";
|
|
1
|
+
import { ARCHITECT_DEBUG_DISPOSITIONS, ARCHITECT_DEBUG_STATUSES, ARCHITECTURE_BRIEF_STATUSES, ARCHITECTURE_DIAGNOSIS_DISPOSITIONS, ARCHITECTURE_EVIDENCE_STATUSES, ARCHITECTURE_PLAN_RESULTS, CODER_COMPLETION_DECISIONS, DOCS_REPORT_DECISIONS, DOCS_UPDATE_COMMIT_PATTERN, DOCS_UPDATE_COMMIT_RULE, DOCS_SYNC_CORRECTION_OWNERS, FINAL_ACCEPTANCE_DECISIONS, L3_ACTIONS, L3_REQUIRED_VALUES, PLANNING_PROGRESS_STATUSES, STRICT_NONE_VALUE, TEST_INFRASTRUCTURE_STATUSES, TEST_RESULTS } from "./artifact-contract.js";
|
|
2
2
|
import { getArtifactDefinition } from "./artifact-registry.js";
|
|
3
3
|
const PLACEHOLDER_PATTERN = /(^|\n)\s*(TBD|Not run yet\.?|status:\s*draft)\s*(\n|$)/i;
|
|
4
4
|
export function checkMarkdownArtifact(kind, artifactPath, content, options = {}) {
|
|
@@ -252,7 +252,13 @@ function validateArtifactFields(kind, content, mode) {
|
|
|
252
252
|
return invalidFields;
|
|
253
253
|
}
|
|
254
254
|
if (kind === "docs-update-report") {
|
|
255
|
-
|
|
255
|
+
const invalidFields = validateDecision(content, DOCS_REPORT_DECISIONS);
|
|
256
|
+
const decision = readArtifactSectionContent(content, "Decision")?.trim().toLowerCase();
|
|
257
|
+
const commit = readArtifactSectionContent(content, "Commit");
|
|
258
|
+
if (mode === "final" && decision === "synced" && !DOCS_UPDATE_COMMIT_PATTERN.test(commit ?? "")) {
|
|
259
|
+
invalidFields.push(`${DOCS_UPDATE_COMMIT_RULE} Received Commit: ${JSON.stringify(commit ?? "")}.`);
|
|
260
|
+
}
|
|
261
|
+
return invalidFields;
|
|
256
262
|
}
|
|
257
263
|
if (kind === "docs-sync-report") {
|
|
258
264
|
const invalidFields = validateDecision(content, DOCS_REPORT_DECISIONS);
|
|
@@ -30,6 +30,8 @@ export const TEST_INFRASTRUCTURE_STATUSES = [
|
|
|
30
30
|
export const L3_REQUIRED_VALUES = ["yes", "no"];
|
|
31
31
|
export const L3_ACTIONS = ["run-existing", "updated", "added"];
|
|
32
32
|
export const DOCS_REPORT_DECISIONS = ["synced", "unchanged", "blocked"];
|
|
33
|
+
export const DOCS_UPDATE_COMMIT_PATTERN = /^[0-9a-f]{7,40}$/;
|
|
34
|
+
export const DOCS_UPDATE_COMMIT_RULE = "When Decision is synced, Commit must contain only one bare lowercase hexadecimal commit hash (7-40 characters, for example abc1234) on a single line. No backticks, bullets, links, subjects, or extra lines; put explanations in Evidence Reviewed. An unchanged result does not require a new commit.";
|
|
33
35
|
export const DOCS_SYNC_CORRECTION_OWNERS = ["none", "architect", "coder", "tester"];
|
|
34
36
|
export const FINAL_ACCEPTANCE_DECISIONS = [
|
|
35
37
|
"accepted",
|