agentera 3.0.0-dev.21 → 3.0.0-dev.23
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 +7 -3
- package/bundle/.cursor/agents/agentera.md +1 -1
- package/bundle/.opencode/agents/agentera.md +1 -1
- package/bundle/CHANGELOG.md +11 -0
- package/bundle/references/analysis/evidence-tier-authority.yaml +516 -0
- package/bundle/references/artifacts/state-storage-authority.yaml +109 -3
- package/bundle/references/artifacts/verbosity-budget-authority.yaml +42 -0
- package/bundle/references/cli/agent-ready-state-contract.yaml +22 -14
- package/bundle/references/cli/prime-consumer-compatibility.yaml +676 -0
- package/bundle/references/cli/vocabulary-index.yaml +3 -3
- package/bundle/references/cli/vocabulary.md +10 -3
- package/bundle/skills/agentera/SKILL.md +7 -6
- package/bundle/skills/agentera/agents/audit.toml +1 -1
- package/bundle/skills/agentera/agents/build.toml +1 -1
- package/bundle/skills/agentera/agents/design.toml +1 -1
- package/bundle/skills/agentera/agents/discuss.toml +1 -1
- package/bundle/skills/agentera/agents/document.toml +1 -1
- package/bundle/skills/agentera/agents/optimize.toml +1 -1
- package/bundle/skills/agentera/agents/orchestrate.toml +1 -1
- package/bundle/skills/agentera/agents/plan.toml +1 -1
- package/bundle/skills/agentera/agents/profile.toml +1 -1
- package/bundle/skills/agentera/agents/research.toml +1 -1
- package/bundle/skills/agentera/agents/status.toml +1 -1
- package/bundle/skills/agentera/agents/vision.toml +1 -1
- package/bundle/skills/agentera/capabilities/profile/schemas/validation.yaml +31 -3
- package/bundle/skills/agentera/schemas/artifacts/changelog.yaml +1 -0
- package/bundle/skills/agentera/schemas/artifacts/design.yaml +1 -0
- package/bundle/skills/agentera/schemas/artifacts/todo.yaml +1 -0
- package/dist/analytics/extractCorpus/cli.js +33 -5
- package/dist/analytics/extractCorpus/cli.js.map +1 -1
- package/dist/analytics/extractCorpus/evidenceTiers.js +561 -0
- package/dist/analytics/extractCorpus/evidenceTiers.js.map +1 -0
- package/dist/analytics/extractCorpus/extractCorpusParity.js +1 -0
- package/dist/analytics/extractCorpus/extractCorpusParity.js.map +1 -1
- package/dist/analytics/extractCorpus/index.js +3 -0
- package/dist/analytics/extractCorpus/index.js.map +1 -1
- package/dist/analytics/extractCorpus/tierReader.js +109 -0
- package/dist/analytics/extractCorpus/tierReader.js.map +1 -0
- package/dist/analytics/profileSignals.js +212 -0
- package/dist/analytics/profileSignals.js.map +1 -0
- package/dist/analytics/usageStats.js +104 -20
- package/dist/analytics/usageStats.js.map +1 -1
- package/dist/capabilities/index.js +2 -1
- package/dist/capabilities/index.js.map +1 -1
- package/dist/capabilities/profile/instructions.js +1 -1
- package/dist/capabilities/profile/instructions.js.map +1 -1
- package/dist/capabilities/status/startupInstructions.js +35 -0
- package/dist/capabilities/status/startupInstructions.js.map +1 -0
- package/dist/cli/capabilityContext/build.js +3 -3
- package/dist/cli/capabilityContext/build.js.map +1 -1
- package/dist/cli/capabilityContext/closeout.js +5 -5
- package/dist/cli/capabilityContext/closeout.js.map +1 -1
- package/dist/cli/capabilityContext/contract.js +4 -4
- package/dist/cli/capabilityContext/contract.js.map +1 -1
- package/dist/cli/capabilityContext/evidence.js +4 -4
- package/dist/cli/capabilityContext/evidence.js.map +1 -1
- package/dist/cli/capabilityContext/planState.js +7 -6
- package/dist/cli/capabilityContext/planState.js.map +1 -1
- package/dist/cli/capabilityContext/shared.js +1 -1
- package/dist/cli/capabilityContext/shared.js.map +1 -1
- package/dist/cli/capabilityContext/startup.js +4 -4
- package/dist/cli/capabilityContext/startup.js.map +1 -1
- package/dist/cli/commands/lint.js +10 -2
- package/dist/cli/commands/lint.js.map +1 -1
- package/dist/cli/commands/prime/briefOrientation.js +582 -0
- package/dist/cli/commands/prime/briefOrientation.js.map +1 -0
- package/dist/cli/commands/prime/collectOrientationState.js +3 -0
- package/dist/cli/commands/prime/collectOrientationState.js.map +1 -1
- package/dist/cli/commands/prime/orientationOutput.js +117 -23
- package/dist/cli/commands/prime/orientationOutput.js.map +1 -1
- package/dist/cli/commands/prime.js +30 -3
- package/dist/cli/commands/prime.js.map +1 -1
- package/dist/cli/commands/report.js +55 -15
- package/dist/cli/commands/report.js.map +1 -1
- package/dist/cli/commands/schema.js +3 -29
- package/dist/cli/commands/schema.js.map +1 -1
- package/dist/cli/commands/state/plan.js +3 -2
- package/dist/cli/commands/state/plan.js.map +1 -1
- package/dist/cli/help.js +1 -1
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/orientation/corpusCoverage.js +32 -0
- package/dist/cli/orientation/corpusCoverage.js.map +1 -1
- package/dist/cli/orientation.js +3 -3
- package/dist/cli/orientation.js.map +1 -1
- package/dist/cli/startupCompletenessContract.js +3 -3
- package/dist/cli/startupCompletenessContract.js.map +1 -1
- package/dist/cli/stateQuery.js +37 -0
- package/dist/cli/stateQuery.js.map +1 -1
- package/dist/registries/evidenceTierContract.js +362 -0
- package/dist/registries/evidenceTierContract.js.map +1 -0
- package/dist/registries/verbosityBudgetContract.js +206 -0
- package/dist/registries/verbosityBudgetContract.js.map +1 -0
- package/dist/state/decisionLegacyValidation.js +185 -0
- package/dist/state/decisionLegacyValidation.js.map +1 -0
- package/dist/state/decisionOverlay.js +24 -1
- package/dist/state/decisionOverlay.js.map +1 -1
- package/dist/state/decisionRevision.js +622 -0
- package/dist/state/decisionRevision.js.map +1 -0
- package/dist/state/decisionRevisionPublication.js +532 -0
- package/dist/state/decisionRevisionPublication.js.map +1 -0
- package/dist/state/directRetrieval.js +55 -4
- package/dist/state/directRetrieval.js.map +1 -1
- package/dist/state/listRetrieval.js +42 -11
- package/dist/state/listRetrieval.js.map +1 -1
- package/dist/state/startupAnalysis/benchmark.js +70 -8
- package/dist/state/startupAnalysis/benchmark.js.map +1 -1
- package/dist/state/startupAnalysis/threshold.js +13 -0
- package/dist/state/startupAnalysis/threshold.js.map +1 -1
- package/dist/state/startupProjection.js +68 -1
- package/dist/state/startupProjection.js.map +1 -1
- package/dist/state/write/candidateMutation.js +331 -0
- package/dist/state/write/candidateMutation.js.map +1 -0
- package/dist/state/write/explain.js +36 -12
- package/dist/state/write/explain.js.map +1 -1
- package/dist/state/write/helpers.js +22 -0
- package/dist/state/write/helpers.js.map +1 -1
- package/dist/state/write/mutation.js +42 -0
- package/dist/state/write/mutation.js.map +1 -1
- package/dist/state/write/operations.js +49 -1
- package/dist/state/write/operations.js.map +1 -1
- package/dist/state/write/transaction.js +23 -357
- package/dist/state/write/transaction.js.map +1 -1
- package/dist/validate/lifecycleAdapters/lifecycleMain.js +154 -0
- package/dist/validate/lifecycleAdapters/lifecycleMain.js.map +1 -0
- package/dist/validate/lifecycleAdapters.js +5 -156
- package/dist/validate/lifecycleAdapters.js.map +1 -1
- package/dist/validate/selfAudit.js +38 -43
- package/dist/validate/selfAudit.js.map +1 -1
- package/package.json +2 -2
|
@@ -2,6 +2,7 @@ export const WRITABLE_ARTIFACTS = ["progress", "decisions", "plan", "health", "e
|
|
|
2
2
|
export const WRITE_VERBS = [
|
|
3
3
|
"append",
|
|
4
4
|
"update",
|
|
5
|
+
"amend",
|
|
5
6
|
"set-status",
|
|
6
7
|
"set-plan-status",
|
|
7
8
|
"record-evaluation",
|
|
@@ -11,6 +12,8 @@ export const WRITE_VERBS = [
|
|
|
11
12
|
"publish",
|
|
12
13
|
"explain",
|
|
13
14
|
];
|
|
15
|
+
/** Caller-selected existing decision number (update/amend). Never CLI-assigned. */
|
|
16
|
+
const EXISTING_DECISION_NUMBER_DESCRIPTION = "Existing decision number to update or amend. Caller-selected: it must match a numbered decision in the active projection or numbered archive and is never assigned by the CLI.";
|
|
14
17
|
const progressAppend = [
|
|
15
18
|
{
|
|
16
19
|
flag: "--type",
|
|
@@ -60,7 +63,13 @@ const decisionAppend = [
|
|
|
60
63
|
{ flag: "--date", field: "date", kind: "date", required: false },
|
|
61
64
|
];
|
|
62
65
|
const decisionUpdate = [
|
|
63
|
-
{
|
|
66
|
+
{
|
|
67
|
+
flag: "--number",
|
|
68
|
+
field: "number",
|
|
69
|
+
kind: "integer",
|
|
70
|
+
required: true,
|
|
71
|
+
description: EXISTING_DECISION_NUMBER_DESCRIPTION,
|
|
72
|
+
},
|
|
64
73
|
{
|
|
65
74
|
flag: "--satisfaction-state",
|
|
66
75
|
field: "satisfaction.state",
|
|
@@ -72,6 +81,44 @@ const decisionUpdate = [
|
|
|
72
81
|
{ flag: "--confirmed-by", field: "satisfaction.user_confirmation.confirmed_by", kind: "string" },
|
|
73
82
|
{ flag: "--confirmed-at", field: "satisfaction.user_confirmation.confirmed_at", kind: "string" },
|
|
74
83
|
];
|
|
84
|
+
/**
|
|
85
|
+
* Amending decision content fields. `--number` is caller-selected (an existing
|
|
86
|
+
* decision). At least one amendable content field must be supplied; individual
|
|
87
|
+
* fields are optional so the writer can validate the union requirement.
|
|
88
|
+
* `--alternative-rejected` is repeatable and appends rejected alternatives.
|
|
89
|
+
* Confidence values must be current vocabulary (firm|provisional|exploratory).
|
|
90
|
+
* Amendment publication publishes a record-local revision document override
|
|
91
|
+
* with recovery; the decisions projection is never rewritten.
|
|
92
|
+
*/
|
|
93
|
+
const decisionAmend = [
|
|
94
|
+
{
|
|
95
|
+
flag: "--number",
|
|
96
|
+
field: "number",
|
|
97
|
+
kind: "integer",
|
|
98
|
+
required: true,
|
|
99
|
+
description: EXISTING_DECISION_NUMBER_DESCRIPTION,
|
|
100
|
+
},
|
|
101
|
+
{ flag: "--question", field: "question", kind: "string", required: false },
|
|
102
|
+
{ flag: "--context", field: "context", kind: "string", required: false },
|
|
103
|
+
{ flag: "--alternative-chosen", field: "alternatives.chosen", kind: "string", required: false },
|
|
104
|
+
{
|
|
105
|
+
flag: "--alternative-rejected",
|
|
106
|
+
field: "alternatives.rejected",
|
|
107
|
+
kind: "string_list",
|
|
108
|
+
repeatable: true,
|
|
109
|
+
required: false,
|
|
110
|
+
},
|
|
111
|
+
{ flag: "--choice", field: "choice", kind: "string", required: false },
|
|
112
|
+
{ flag: "--reasoning", field: "reasoning", kind: "string", required: false },
|
|
113
|
+
{
|
|
114
|
+
flag: "--confidence",
|
|
115
|
+
field: "confidence",
|
|
116
|
+
kind: "string",
|
|
117
|
+
required: false,
|
|
118
|
+
validValues: ["firm", "provisional", "exploratory"],
|
|
119
|
+
},
|
|
120
|
+
{ flag: "--feeds-into", field: "feeds_into", kind: "string", required: false },
|
|
121
|
+
];
|
|
75
122
|
const planTaskFields = [
|
|
76
123
|
{ flag: "--name", field: "name", kind: "string", required: true },
|
|
77
124
|
{ flag: "--depends-on", field: "depends_on", kind: "integer_list", repeatable: true },
|
|
@@ -109,6 +156,7 @@ const SPECS = [
|
|
|
109
156
|
{ artifact: "progress", verb: "append", fields: progressAppend, compacts: true },
|
|
110
157
|
{ artifact: "decisions", verb: "append", fields: decisionAppend, compacts: true },
|
|
111
158
|
{ artifact: "decisions", verb: "update", fields: decisionUpdate },
|
|
159
|
+
{ artifact: "decisions", verb: "amend", fields: decisionAmend },
|
|
112
160
|
{ artifact: "plan", verb: "append", fields: planTaskFields },
|
|
113
161
|
{
|
|
114
162
|
artifact: "plan",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operations.js","sourceRoot":"","sources":["../../../src/state/write/operations.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,CAAU,CAAC;AAGtG,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,QAAQ;IACR,QAAQ;IACR,YAAY;IACZ,iBAAiB;IACjB,mBAAmB;IACnB,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,SAAS;IACT,SAAS;CACD,CAAC;
|
|
1
|
+
{"version":3,"file":"operations.js","sourceRoot":"","sources":["../../../src/state/write/operations.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,37 +7,21 @@ import { dumpYamlMapping, loadYamlMapping } from "../../core/yaml.js";
|
|
|
7
7
|
import { compactYamlFile, decisionProtectedOverflowCount, } from "../../hooks/compaction/index.js";
|
|
8
8
|
import { assertRealpathBoundary, loadArtifactRegistry, resolveArtifactPath, } from "../../registries/artifactRegistry.js";
|
|
9
9
|
import { withStateMutation, } from "./mutation.js";
|
|
10
|
-
import {
|
|
10
|
+
import { nextEntryNumber } from "./assign.js";
|
|
11
|
+
import { mutateCandidate, normalizedDecisionPayload } from "./candidateMutation.js";
|
|
12
|
+
import { array, findByNumber, mapping, schemaViolation } from "./helpers.js";
|
|
11
13
|
import { reject } from "./errors.js";
|
|
12
|
-
import { findByNumber, schemaViolation } from "./helpers.js";
|
|
13
14
|
import { validateArtifactBytes } from "./validate.js";
|
|
14
15
|
import { planEvaluationViolations, validatePlanCreateInput, validatePlanPublicationCandidate, } from "./planPublication.js";
|
|
15
16
|
import { dependencyReadyTasks } from "../../cli/capabilityContext/planState.js";
|
|
16
17
|
import { publishImmutableFile, } from "../archivePublication.js";
|
|
17
|
-
import { findArchivedReplay
|
|
18
|
+
import { findArchivedReplay } from "../archiveReplay.js";
|
|
18
19
|
import { discoverNumberedArchives } from "../archiveDiscovery.js";
|
|
19
20
|
import { hydrateDecisionRecords, updateDecisionOverlay, } from "../decisionOverlay.js";
|
|
20
|
-
import {
|
|
21
|
+
import { dispatchDecisionAmendment } from "../decisionRevisionPublication.js";
|
|
22
|
+
import { decisionLegacyCoexistence, gateCandidateDecisions, gateCompactedDecisions, gateExistingDecisions, } from "../decisionLegacyValidation.js";
|
|
23
|
+
import { repairHealthProjectionBytes } from "../healthRepair.js";
|
|
21
24
|
import { executeExperimentPublication } from "./experimentPublication.js";
|
|
22
|
-
function mapping(value) {
|
|
23
|
-
return value && typeof value === "object" && !Array.isArray(value)
|
|
24
|
-
? value
|
|
25
|
-
: {};
|
|
26
|
-
}
|
|
27
|
-
function array(doc, key) {
|
|
28
|
-
return Array.isArray(doc[key])
|
|
29
|
-
? doc[key].filter((v) => Boolean(v && typeof v === "object" && !Array.isArray(v)))
|
|
30
|
-
: [];
|
|
31
|
-
}
|
|
32
|
-
function mappingPath(entry, field) {
|
|
33
|
-
let value = entry;
|
|
34
|
-
for (const part of field.split(".")) {
|
|
35
|
-
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
36
|
-
return undefined;
|
|
37
|
-
value = value[part];
|
|
38
|
-
}
|
|
39
|
-
return value;
|
|
40
|
-
}
|
|
41
25
|
function readExisting(target) {
|
|
42
26
|
if (!fs.existsSync(target))
|
|
43
27
|
return { doc: {}, bytes: "" };
|
|
@@ -49,329 +33,6 @@ function readExisting(target) {
|
|
|
49
33
|
throw new Error(`cannot parse existing artifact '${target}': ${error.message}; run agentera check validate artifact before retrying`);
|
|
50
34
|
}
|
|
51
35
|
}
|
|
52
|
-
function buildProgress(doc, values) {
|
|
53
|
-
const entry = {
|
|
54
|
-
number: nextEntryNumber(doc, "cycles"),
|
|
55
|
-
timestamp: values.timestamp ?? localTimestamp(),
|
|
56
|
-
type: values.type,
|
|
57
|
-
phase: values.phase,
|
|
58
|
-
what: values.what,
|
|
59
|
-
};
|
|
60
|
-
for (const field of ["inspiration", "discovered", "verified", "next"])
|
|
61
|
-
if (values[field] !== undefined)
|
|
62
|
-
entry[field] = values[field];
|
|
63
|
-
const context = { intent: mappingPath(values, "context.intent") };
|
|
64
|
-
for (const field of ["constraints", "unknowns", "scope"]) {
|
|
65
|
-
const value = mappingPath(values, `context.${field}`);
|
|
66
|
-
if (value !== undefined)
|
|
67
|
-
context[field] = value;
|
|
68
|
-
}
|
|
69
|
-
entry.context = context;
|
|
70
|
-
return entry;
|
|
71
|
-
}
|
|
72
|
-
function buildDecision(doc, values) {
|
|
73
|
-
const alternatives = mapping(values.alternatives);
|
|
74
|
-
const rejected = Array.isArray(alternatives.rejected) ? alternatives.rejected : [];
|
|
75
|
-
const entry = {
|
|
76
|
-
number: nextEntryNumber(doc, "decisions"),
|
|
77
|
-
date: values.date ?? localDate(),
|
|
78
|
-
question: values.question,
|
|
79
|
-
context: values.context,
|
|
80
|
-
alternatives: [
|
|
81
|
-
{ name: alternatives.chosen, status: "chosen" },
|
|
82
|
-
...rejected.map((name) => ({ name, status: "rejected" })),
|
|
83
|
-
],
|
|
84
|
-
choice: values.choice,
|
|
85
|
-
reasoning: values.reasoning,
|
|
86
|
-
confidence: values.confidence,
|
|
87
|
-
};
|
|
88
|
-
if (values.feeds_into !== undefined)
|
|
89
|
-
entry.feeds_into = values.feeds_into;
|
|
90
|
-
return entry;
|
|
91
|
-
}
|
|
92
|
-
function normalizedDecisionPayload(values) {
|
|
93
|
-
const payload = { ...values };
|
|
94
|
-
const alternatives = mapping(values.alternatives);
|
|
95
|
-
payload.alternatives = [
|
|
96
|
-
{ name: alternatives.chosen, status: "chosen" },
|
|
97
|
-
...(Array.isArray(alternatives.rejected) ? alternatives.rejected : []).map((name) => ({
|
|
98
|
-
name,
|
|
99
|
-
status: "rejected",
|
|
100
|
-
})),
|
|
101
|
-
];
|
|
102
|
-
return payload;
|
|
103
|
-
}
|
|
104
|
-
function mutateCandidate(req, doc, recovered) {
|
|
105
|
-
const candidate = structuredClone(doc);
|
|
106
|
-
if (req.artifact === "progress") {
|
|
107
|
-
const payload = req.callerPayload;
|
|
108
|
-
const entries = array(candidate, "cycles");
|
|
109
|
-
const replay = entries.find((entry) => isExactArchiveReplay(entry, payload));
|
|
110
|
-
if (replay)
|
|
111
|
-
return {
|
|
112
|
-
candidate,
|
|
113
|
-
written: replay,
|
|
114
|
-
assigned: { number: replay.number, timestamp: replay.timestamp },
|
|
115
|
-
replay: true,
|
|
116
|
-
};
|
|
117
|
-
if (recovered) {
|
|
118
|
-
recoverArchivedEntry(candidate, "cycles", entries, recovered, true);
|
|
119
|
-
return {
|
|
120
|
-
candidate,
|
|
121
|
-
written: recovered,
|
|
122
|
-
assigned: { number: recovered.number, timestamp: recovered.timestamp },
|
|
123
|
-
replay: true,
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
const entry = buildProgress(candidate, req.values);
|
|
127
|
-
candidate.cycles = [entry, ...entries];
|
|
128
|
-
return {
|
|
129
|
-
candidate,
|
|
130
|
-
written: entry,
|
|
131
|
-
assigned: { number: entry.number, timestamp: entry.timestamp },
|
|
132
|
-
replay: false,
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
if (req.artifact === "decisions" && req.spec.verb === "append") {
|
|
136
|
-
const entries = array(candidate, "decisions");
|
|
137
|
-
const payload = normalizedDecisionPayload(req.callerPayload);
|
|
138
|
-
const replay = entries.find((entry) => isExactArchiveReplay(entry, payload));
|
|
139
|
-
if (replay) {
|
|
140
|
-
const entry = replay;
|
|
141
|
-
return {
|
|
142
|
-
candidate,
|
|
143
|
-
written: entry,
|
|
144
|
-
assigned: { number: entry.number, date: entry.date },
|
|
145
|
-
replay: true,
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
if (recovered) {
|
|
149
|
-
recoverArchivedEntry(candidate, "decisions", entries, recovered, false);
|
|
150
|
-
return {
|
|
151
|
-
candidate,
|
|
152
|
-
written: recovered,
|
|
153
|
-
assigned: { number: recovered.number, date: recovered.date },
|
|
154
|
-
replay: true,
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
const entry = buildDecision(candidate, req.values);
|
|
158
|
-
candidate.decisions = [...entries, entry];
|
|
159
|
-
return {
|
|
160
|
-
candidate,
|
|
161
|
-
written: entry,
|
|
162
|
-
assigned: { number: entry.number, date: entry.date },
|
|
163
|
-
replay: false,
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
if (req.artifact === "health") {
|
|
167
|
-
if (req.spec.verb === "repair") {
|
|
168
|
-
if (!req.force)
|
|
169
|
-
reject({ class: "conflict", message: "health repair requires --force; use --dry-run to preview the edit" });
|
|
170
|
-
const number = Number(req.values.number);
|
|
171
|
-
const keep = req.values.keep === "last" ? "last" : "first";
|
|
172
|
-
const repaired = repairHealthDuplicates(candidate, number, keep);
|
|
173
|
-
if (repaired.removed === 0)
|
|
174
|
-
reject({ class: "unsupported_target", message: `health audit ${number} has no duplicate current-history rows to repair` });
|
|
175
|
-
return { candidate: repaired.candidate, written: { number, removed_rows: repaired.removed, retained: keep }, assigned: { number, removed_rows: repaired.removed }, replay: false };
|
|
176
|
-
}
|
|
177
|
-
if (req.input && ("audits" in req.input || "archive" in req.input)) {
|
|
178
|
-
reject({
|
|
179
|
-
class: "schema_violation",
|
|
180
|
-
message: "health append input must be one audit entry, not a whole health artifact",
|
|
181
|
-
violations: ["remove audits/archive wrapper fields"],
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
const entries = array(candidate, "audits");
|
|
185
|
-
const payload = req.callerPayload;
|
|
186
|
-
const replay = entries.find((entry) => isExactArchiveReplay(entry, payload));
|
|
187
|
-
if (replay) {
|
|
188
|
-
const entry = replay;
|
|
189
|
-
return {
|
|
190
|
-
candidate,
|
|
191
|
-
written: entry,
|
|
192
|
-
assigned: { number: entry.number, date: entry.date },
|
|
193
|
-
replay: true,
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
if (recovered) {
|
|
197
|
-
recoverArchivedEntry(candidate, "audits", entries, recovered, false);
|
|
198
|
-
return {
|
|
199
|
-
candidate,
|
|
200
|
-
written: recovered,
|
|
201
|
-
assigned: { number: recovered.number, date: recovered.date },
|
|
202
|
-
replay: true,
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
const entry = {
|
|
206
|
-
number: nextEntryNumber(candidate, "audits"),
|
|
207
|
-
date: req.input?.date ?? localDate(),
|
|
208
|
-
...req.input,
|
|
209
|
-
};
|
|
210
|
-
candidate.audits = [...entries, entry];
|
|
211
|
-
return {
|
|
212
|
-
candidate,
|
|
213
|
-
written: entry,
|
|
214
|
-
assigned: { number: entry.number, date: entry.date },
|
|
215
|
-
replay: false,
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
const tasks = array(candidate, "tasks");
|
|
219
|
-
if (req.spec.verb === "append") {
|
|
220
|
-
const sameName = tasks.find((task) => task.name === req.values.name);
|
|
221
|
-
const payload = req.callerPayload;
|
|
222
|
-
if (sameName) {
|
|
223
|
-
if (isExactArchiveReplay(sameName, payload))
|
|
224
|
-
return {
|
|
225
|
-
candidate,
|
|
226
|
-
written: sameName,
|
|
227
|
-
assigned: { number: sameName.number },
|
|
228
|
-
replay: true,
|
|
229
|
-
};
|
|
230
|
-
reject({
|
|
231
|
-
class: "conflict",
|
|
232
|
-
message: `plan task "${req.values.name}" exists with different fields; use 'state plan update --task ${sameName.number}' to modify it`,
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
const entry = {
|
|
236
|
-
number: nextTaskNumber(candidate),
|
|
237
|
-
name: req.values.name,
|
|
238
|
-
status: req.values.status ?? "pending",
|
|
239
|
-
};
|
|
240
|
-
for (const field of ["depends_on", "acceptance"])
|
|
241
|
-
if (req.values[field] !== undefined)
|
|
242
|
-
entry[field] = req.values[field];
|
|
243
|
-
candidate.tasks = [...tasks, entry];
|
|
244
|
-
return { candidate, written: entry, assigned: { number: entry.number }, replay: false };
|
|
245
|
-
}
|
|
246
|
-
if (req.spec.verb === "update") {
|
|
247
|
-
const number = Number(req.values.task);
|
|
248
|
-
const entry = findByNumber(tasks, number);
|
|
249
|
-
if (!entry)
|
|
250
|
-
reject({ class: "unsupported_target", message: `no plan task with number ${number}` });
|
|
251
|
-
let changed = false;
|
|
252
|
-
for (const field of [
|
|
253
|
-
"name",
|
|
254
|
-
"depends_on",
|
|
255
|
-
"acceptance",
|
|
256
|
-
"status",
|
|
257
|
-
"evidence",
|
|
258
|
-
"blocked_reason",
|
|
259
|
-
]) {
|
|
260
|
-
if (req.values[field] !== undefined && !isDeepStrictEqual(entry[field], req.values[field])) {
|
|
261
|
-
entry[field] = req.values[field];
|
|
262
|
-
changed = true;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
if (req.values.surprise !== undefined) {
|
|
266
|
-
const current = String(candidate.surprises ?? "").trim();
|
|
267
|
-
const surprise = String(req.values.surprise);
|
|
268
|
-
if (!current.split("\n").includes(surprise)) {
|
|
269
|
-
candidate.surprises = current ? `${current}\n${surprise}` : surprise;
|
|
270
|
-
changed = true;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
return { candidate, written: entry, assigned: { number }, replay: !changed };
|
|
274
|
-
}
|
|
275
|
-
if (req.spec.verb === "set-plan-status") {
|
|
276
|
-
const status = String(req.values.status);
|
|
277
|
-
if (status === "complete" && tasks.some((task) => task.status !== "complete")) {
|
|
278
|
-
reject({
|
|
279
|
-
class: "conflict",
|
|
280
|
-
message: "plan cannot be marked complete while incomplete tasks remain",
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
const header = mapping(candidate.header);
|
|
284
|
-
const replay = header.status === status;
|
|
285
|
-
header.status = status;
|
|
286
|
-
candidate.header = header;
|
|
287
|
-
return { candidate, written: header, assigned: {}, replay };
|
|
288
|
-
}
|
|
289
|
-
if (req.spec.verb === "set-status") {
|
|
290
|
-
const taskNumber = Number(req.values.task);
|
|
291
|
-
const status = String(req.values.status);
|
|
292
|
-
if (!["complete", "in_progress", "pending", "blocked"].includes(status))
|
|
293
|
-
reject({
|
|
294
|
-
class: "invalid_choice",
|
|
295
|
-
message: `argument --status: invalid choice: '${status}'`,
|
|
296
|
-
valid_values: ["complete", "in_progress", "pending", "blocked"],
|
|
297
|
-
});
|
|
298
|
-
const entry = findByNumber(tasks, taskNumber);
|
|
299
|
-
if (!entry)
|
|
300
|
-
reject({ class: "unsupported_target", message: `no plan task with number ${taskNumber}` });
|
|
301
|
-
const replay = entry.status === status;
|
|
302
|
-
entry.status = status;
|
|
303
|
-
return { candidate, written: entry, assigned: { number: taskNumber }, replay };
|
|
304
|
-
}
|
|
305
|
-
if (req.spec.verb === "record-evaluation") {
|
|
306
|
-
const taskNumber = Number(req.values.task);
|
|
307
|
-
const entry = findByNumber(tasks, taskNumber);
|
|
308
|
-
if (!entry)
|
|
309
|
-
reject({ class: "unsupported_target", message: `no plan task with number ${taskNumber}` });
|
|
310
|
-
const evaluationInput = mapping(req.values.evaluation);
|
|
311
|
-
const attemptId = String(evaluationInput.attempt_id ?? "").trim();
|
|
312
|
-
const verdict = String(evaluationInput.verdict ?? "");
|
|
313
|
-
const provenance = String(evaluationInput.provenance ?? "").trim();
|
|
314
|
-
const failureEvidence = String(evaluationInput.failure_evidence ?? "").trim();
|
|
315
|
-
if (!attemptId || !provenance)
|
|
316
|
-
reject({ class: "schema_violation", message: "evaluation requires non-empty --attempt-id and --provenance" });
|
|
317
|
-
if (verdict === "fail" && !failureEvidence)
|
|
318
|
-
reject({ class: "schema_violation", message: "a failed evaluation requires non-empty --failure-evidence" });
|
|
319
|
-
if (verdict === "pass" && failureEvidence)
|
|
320
|
-
reject({ class: "schema_violation", message: "--failure-evidence applies only to a failed evaluation" });
|
|
321
|
-
const prior = mapping(entry.evaluation);
|
|
322
|
-
const priorProvenance = mapping(prior.provenance);
|
|
323
|
-
if (priorProvenance.attempt_id === attemptId) {
|
|
324
|
-
const replay = prior.last_verdict === verdict &&
|
|
325
|
-
priorProvenance.source === provenance &&
|
|
326
|
-
(verdict !== "fail" || prior.last_failure_evidence === failureEvidence);
|
|
327
|
-
if (!replay)
|
|
328
|
-
reject({
|
|
329
|
-
class: "conflict",
|
|
330
|
-
message: `evaluation attempt '${attemptId}' already exists with different result data`,
|
|
331
|
-
});
|
|
332
|
-
return {
|
|
333
|
-
candidate,
|
|
334
|
-
written: entry,
|
|
335
|
-
assigned: { number: taskNumber, attempt_count: prior.attempt_count ?? 0 },
|
|
336
|
-
replay: true,
|
|
337
|
-
};
|
|
338
|
-
}
|
|
339
|
-
if (["complete", "blocked"].includes(String(entry.status ?? "")))
|
|
340
|
-
reject({ class: "conflict", message: `plan task ${taskNumber} is ${entry.status} and cannot accept another evaluation` });
|
|
341
|
-
const attemptCount = Number(prior.attempt_count ?? 0);
|
|
342
|
-
const failureCount = Number(prior.failure_count ?? 0);
|
|
343
|
-
if (!Number.isInteger(attemptCount) || attemptCount < 0 || !Number.isInteger(failureCount) || failureCount < 0)
|
|
344
|
-
reject({ class: "schema_violation", message: `plan task ${taskNumber} has malformed evaluation state` });
|
|
345
|
-
if (verdict === "fail" && failureCount >= 2)
|
|
346
|
-
reject({ class: "conflict", message: `plan task ${taskNumber} has exhausted its evaluation retry budget` });
|
|
347
|
-
const nextFailureCount = failureCount + (verdict === "fail" ? 1 : 0);
|
|
348
|
-
entry.evaluation = {
|
|
349
|
-
attempt_count: attemptCount + 1,
|
|
350
|
-
failure_count: nextFailureCount,
|
|
351
|
-
last_verdict: verdict,
|
|
352
|
-
last_failure_evidence: verdict === "fail" ? failureEvidence : prior.last_failure_evidence ?? null,
|
|
353
|
-
provenance: {
|
|
354
|
-
attempt_id: attemptId,
|
|
355
|
-
source: provenance,
|
|
356
|
-
recorded_at: localTimestamp(),
|
|
357
|
-
writer_command: "agentera state plan record-evaluation",
|
|
358
|
-
},
|
|
359
|
-
};
|
|
360
|
-
if (nextFailureCount >= 2)
|
|
361
|
-
entry.status = "blocked";
|
|
362
|
-
return {
|
|
363
|
-
candidate,
|
|
364
|
-
written: entry,
|
|
365
|
-
assigned: {
|
|
366
|
-
number: taskNumber,
|
|
367
|
-
attempt_count: attemptCount + 1,
|
|
368
|
-
failure_count: nextFailureCount,
|
|
369
|
-
},
|
|
370
|
-
replay: false,
|
|
371
|
-
};
|
|
372
|
-
}
|
|
373
|
-
throw new Error(`unsupported transaction ${req.artifact} ${req.spec.verb}`);
|
|
374
|
-
}
|
|
375
36
|
function activeKey(artifact) {
|
|
376
37
|
return artifact === "progress"
|
|
377
38
|
? "cycles"
|
|
@@ -644,6 +305,8 @@ function envelope(req, target, finalDoc, written, assigned, replay, compaction,
|
|
|
644
305
|
? { diagnostics: extra.validationDiagnostics }
|
|
645
306
|
: {}),
|
|
646
307
|
},
|
|
308
|
+
...(extra.compatibilityCaveats?.length
|
|
309
|
+
? { compatibility: { legacy_caveats: extra.compatibilityCaveats } } : {}),
|
|
647
310
|
compaction: compaction && req.artifact === "decisions"
|
|
648
311
|
? { ...compaction, protected_overflow_count: extra.protectedOverflowCount ?? 0 }
|
|
649
312
|
: compaction,
|
|
@@ -656,6 +319,9 @@ function envelope(req, target, finalDoc, written, assigned, replay, compaction,
|
|
|
656
319
|
return result;
|
|
657
320
|
}
|
|
658
321
|
export function executeStateWrite(req, options = {}) {
|
|
322
|
+
if (req.artifact === "decisions" && req.spec.verb === "amend") {
|
|
323
|
+
return dispatchDecisionAmendment(req, options);
|
|
324
|
+
}
|
|
659
325
|
assertWriterBoundary(req.projectRoot, path.join(req.projectRoot, ".agentera"), "writer lock");
|
|
660
326
|
const planPublication = req.artifact === "plan" && ["archive", "create"].includes(req.spec.verb);
|
|
661
327
|
if (req.dryRun && planPublication)
|
|
@@ -682,12 +348,13 @@ function executeStateWriteUnlocked(req, transaction) {
|
|
|
682
348
|
const legacyLifecycle = req.artifact === "plan" && ["active", "completed"].includes(String(mapping(existing.doc.header).status ?? ""));
|
|
683
349
|
if (legacyLifecycle)
|
|
684
350
|
existing.doc = canonicalPlanDocumentForWrite(existing.doc);
|
|
351
|
+
const decisionCoexistence = req.artifact === "decisions" ? decisionLegacyCoexistence() : null;
|
|
352
|
+
let decisionLegacyCaveats = [];
|
|
685
353
|
if (existing.bytes) {
|
|
686
354
|
const validationBytes = req.artifact === "plan" ? dumpYamlMapping(existing.doc) : existing.bytes;
|
|
687
355
|
const violations = validateArtifactBytes(req.artifact, validationBytes);
|
|
688
|
-
if (violations.length)
|
|
689
|
-
|
|
690
|
-
}
|
|
356
|
+
if (violations.length)
|
|
357
|
+
decisionLegacyCaveats = gateExistingDecisions(violations, existing.doc, decisionCoexistence, target);
|
|
691
358
|
if (req.artifact === "plan") {
|
|
692
359
|
const evaluationViolations = planEvaluationViolations(existing.doc);
|
|
693
360
|
if (evaluationViolations.length > 0)
|
|
@@ -716,7 +383,7 @@ function executeStateWriteUnlocked(req, transaction) {
|
|
|
716
383
|
const update = updateDecisionOverlay(req.projectRoot, number, req.values.satisfaction, record.satisfaction, transaction, !req.dryRun);
|
|
717
384
|
const before = dumpYamlMapping(update.before);
|
|
718
385
|
const after = dumpYamlMapping(update.after);
|
|
719
|
-
return envelope(req, update.path, existing.doc, { satisfaction: update.satisfaction }, { number }, update.replay, null, { diff: diffText(before, after, update.path), before: update.before, after: update.after });
|
|
386
|
+
return envelope(req, update.path, existing.doc, { satisfaction: update.satisfaction }, { number }, update.replay, null, { diff: diffText(before, after, update.path), before: update.before, after: update.after, compatibilityCaveats: decisionLegacyCaveats });
|
|
720
387
|
}
|
|
721
388
|
if (req.artifact === "plan" && ["archive", "create"].includes(req.spec.verb))
|
|
722
389
|
return planLifecycle(req, target, existing, legacyLifecycle);
|
|
@@ -741,6 +408,7 @@ function executeStateWriteUnlocked(req, transaction) {
|
|
|
741
408
|
return envelope(req, target, mutated.candidate, mutated.written, mutated.assigned, true, null, {
|
|
742
409
|
...(archive ? { archivePath: archive.path } : {}),
|
|
743
410
|
...(req.dryRun ? { diff: "", before: existing.doc, after: mutated.candidate } : {}),
|
|
411
|
+
compatibilityCaveats: decisionLegacyCaveats,
|
|
744
412
|
});
|
|
745
413
|
}
|
|
746
414
|
const repairedBytes = req.artifact === "health" && req.spec.verb === "repair"
|
|
@@ -750,8 +418,7 @@ function executeStateWriteUnlocked(req, transaction) {
|
|
|
750
418
|
reject({ class: "unsupported_target", message: `health audit ${Number(req.values.number)} has no duplicate current-history rows to repair` });
|
|
751
419
|
const candidateBytes = repairedBytes?.bytes ?? dumpYamlMapping(mutated.candidate);
|
|
752
420
|
const candidateViolations = validateArtifactBytes(req.artifact, candidateBytes);
|
|
753
|
-
|
|
754
|
-
schemaViolation(candidateViolations);
|
|
421
|
+
decisionLegacyCaveats = gateCandidateDecisions(candidateViolations, mutated.candidate, decisionCoexistence, Number(mutated.written.number), schemaViolation);
|
|
755
422
|
const stage = req.dryRun
|
|
756
423
|
? stagingPath(req, target)
|
|
757
424
|
: transaction?.stageProjection(target, candidateBytes);
|
|
@@ -769,21 +436,20 @@ function executeStateWriteUnlocked(req, transaction) {
|
|
|
769
436
|
}
|
|
770
437
|
const finalBytes = fs.readFileSync(stage, "utf8");
|
|
771
438
|
const finalViolations = validateArtifactBytes(req.artifact, finalBytes);
|
|
772
|
-
|
|
773
|
-
|
|
439
|
+
const finalDoc = loadYamlMapping(finalBytes);
|
|
440
|
+
decisionLegacyCaveats = gateCompactedDecisions(finalViolations, finalDoc, decisionCoexistence, Number(mutated.written.number));
|
|
774
441
|
if (!req.dryRun)
|
|
775
442
|
transaction?.syncStaged(stage);
|
|
776
|
-
const finalDoc = loadYamlMapping(finalBytes);
|
|
777
443
|
const diff = diffText(existing.bytes, finalBytes, target);
|
|
778
444
|
if (req.dryRun) {
|
|
779
|
-
return envelope(req, target, finalDoc, mutated.written, mutated.assigned, false, compaction, { diff, before: existing.doc, after: finalDoc, protectedOverflowCount });
|
|
445
|
+
return envelope(req, target, finalDoc, mutated.written, mutated.assigned, false, compaction, { diff, before: existing.doc, after: finalDoc, protectedOverflowCount, compatibilityCaveats: decisionLegacyCaveats });
|
|
780
446
|
}
|
|
781
447
|
const archive = numberedAppend
|
|
782
448
|
? transaction?.publishArchive(req.artifact, Number(mutated.written.number), mutated.written)
|
|
783
449
|
: undefined;
|
|
784
450
|
if (!req.dryRun)
|
|
785
451
|
transaction?.publishProjection(stage, target);
|
|
786
|
-
return envelope(req, target, finalDoc, mutated.written, mutated.assigned, mutated.replay, compaction, { ...(archive ? { archivePath: archive.path } : {}), protectedOverflowCount });
|
|
452
|
+
return envelope(req, target, finalDoc, mutated.written, mutated.assigned, mutated.replay, compaction, { ...(archive ? { archivePath: archive.path } : {}), protectedOverflowCount, compatibilityCaveats: decisionLegacyCaveats });
|
|
787
453
|
}
|
|
788
454
|
finally {
|
|
789
455
|
try {
|