omnius 1.0.569 → 1.0.571
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/dist/index.js
CHANGED
|
@@ -43773,20 +43773,27 @@ function scoreSkill(skill, terms2) {
|
|
|
43773
43773
|
const hay = skillHaystack(skill);
|
|
43774
43774
|
const matched = [];
|
|
43775
43775
|
let score = 0;
|
|
43776
|
+
let capabilityMatches = 0;
|
|
43776
43777
|
for (const term of terms2) {
|
|
43777
43778
|
if (!hay.includes(term))
|
|
43778
43779
|
continue;
|
|
43780
|
+
const nameMatch = skill.name.toLowerCase().includes(term);
|
|
43781
|
+
const triggerMatch = skill.triggers.some((trigger) => trigger.toLowerCase().includes(term));
|
|
43782
|
+
const descriptionMatch = skill.description.toLowerCase().includes(term);
|
|
43783
|
+
if (!nameMatch && !triggerMatch && !descriptionMatch)
|
|
43784
|
+
continue;
|
|
43779
43785
|
matched.push(term);
|
|
43780
|
-
|
|
43786
|
+
capabilityMatches++;
|
|
43787
|
+
if (nameMatch)
|
|
43781
43788
|
score += 5;
|
|
43782
|
-
if (
|
|
43789
|
+
if (triggerMatch)
|
|
43783
43790
|
score += 3;
|
|
43784
|
-
if (
|
|
43791
|
+
if (descriptionMatch)
|
|
43785
43792
|
score += 2;
|
|
43786
43793
|
if (skill.source.toLowerCase().includes(term))
|
|
43787
43794
|
score += 1;
|
|
43788
43795
|
}
|
|
43789
|
-
if (score <= 0)
|
|
43796
|
+
if (score <= 0 || capabilityMatches === 0)
|
|
43790
43797
|
return null;
|
|
43791
43798
|
return {
|
|
43792
43799
|
skill,
|
|
@@ -327294,9 +327301,9 @@ ${lanes.join("\n")}
|
|
|
327294
327301
|
}
|
|
327295
327302
|
return flatten2(results);
|
|
327296
327303
|
function visitDirectory(path22, absolutePath, depth2) {
|
|
327297
|
-
const
|
|
327298
|
-
if (visited.has(
|
|
327299
|
-
visited.set(
|
|
327304
|
+
const canonicalPath2 = toCanonical(realpath(absolutePath));
|
|
327305
|
+
if (visited.has(canonicalPath2)) return;
|
|
327306
|
+
visited.set(canonicalPath2, true);
|
|
327300
327307
|
const { files, directories } = getFileSystemEntries(path22);
|
|
327301
327308
|
for (const current of toSorted(files, compareStringsCaseSensitive)) {
|
|
327302
327309
|
const name10 = combinePaths(path22, current);
|
|
@@ -505220,13 +505227,13 @@ ${options2.prefix}` : "\n" : options2.prefix
|
|
|
505220
505227
|
if (!this.typingWatchers) this.typingWatchers = /* @__PURE__ */ new Map();
|
|
505221
505228
|
this.typingWatchers.isInvoked = false;
|
|
505222
505229
|
const createProjectWatcher = (path16, typingsWatcherType) => {
|
|
505223
|
-
const
|
|
505224
|
-
toRemove.delete(
|
|
505225
|
-
if (!this.typingWatchers.has(
|
|
505230
|
+
const canonicalPath2 = this.toPath(path16);
|
|
505231
|
+
toRemove.delete(canonicalPath2);
|
|
505232
|
+
if (!this.typingWatchers.has(canonicalPath2)) {
|
|
505226
505233
|
const watchType = typingsWatcherType === "FileWatcher" ? WatchType.TypingInstallerLocationFile : WatchType.TypingInstallerLocationDirectory;
|
|
505227
505234
|
this.typingWatchers.set(
|
|
505228
|
-
|
|
505229
|
-
canWatchDirectoryOrFilePath(
|
|
505235
|
+
canonicalPath2,
|
|
505236
|
+
canWatchDirectoryOrFilePath(canonicalPath2) ? typingsWatcherType === "FileWatcher" ? this.projectService.watchFactory.watchFile(
|
|
505230
505237
|
path16,
|
|
505231
505238
|
() => !this.typingWatchers.isInvoked ? this.onTypingInstallerWatchInvoke() : this.writeLog(`TypingWatchers already invoked`),
|
|
505232
505239
|
2e3,
|
|
@@ -508514,8 +508521,8 @@ ${options2.prefix}` : "\n" : options2.prefix
|
|
|
508514
508521
|
var _a22;
|
|
508515
508522
|
cleanExtendedConfigCache(this.extendedConfigCache, extendedConfigFilePath, (fileName) => this.toPath(fileName));
|
|
508516
508523
|
let ensureProjectsForOpenFiles = false;
|
|
508517
|
-
(_a22 = this.sharedExtendedConfigFileWatchers.get(extendedConfigFilePath)) == null ? void 0 : _a22.projects.forEach((
|
|
508518
|
-
ensureProjectsForOpenFiles = this.delayUpdateProjectsFromParsedConfigOnConfigFileChange(
|
|
508524
|
+
(_a22 = this.sharedExtendedConfigFileWatchers.get(extendedConfigFilePath)) == null ? void 0 : _a22.projects.forEach((canonicalPath2) => {
|
|
508525
|
+
ensureProjectsForOpenFiles = this.delayUpdateProjectsFromParsedConfigOnConfigFileChange(canonicalPath2, `Change in extended config file ${extendedConfigFileName} detected`) || ensureProjectsForOpenFiles;
|
|
508519
508526
|
});
|
|
508520
508527
|
if (ensureProjectsForOpenFiles) this.delayEnsureProjectForOpenFiles();
|
|
508521
508528
|
},
|
|
@@ -568049,7 +568056,8 @@ function recordCompletionEvidence(ledger, evidence) {
|
|
|
568049
568056
|
...evidence.family ? { family: cleanText(evidence.family, 120) } : {},
|
|
568050
568057
|
...evidence.verificationImpact ? { verificationImpact: evidence.verificationImpact } : {},
|
|
568051
568058
|
...evidence.metrics ? { metrics: evidence.metrics } : {},
|
|
568052
|
-
...evidence.receipt ? { receipt: evidence.receipt } : {}
|
|
568059
|
+
...evidence.receipt ? { receipt: evidence.receipt } : {},
|
|
568060
|
+
...evidence.progressClass ? { progressClass: evidence.progressClass } : {}
|
|
568053
568061
|
};
|
|
568054
568062
|
return {
|
|
568055
568063
|
...ledger,
|
|
@@ -568075,7 +568083,8 @@ function recordToolEvidence(ledger, input) {
|
|
|
568075
568083
|
family: input.family,
|
|
568076
568084
|
verificationImpact: input.verificationImpact,
|
|
568077
568085
|
metrics: input.metrics,
|
|
568078
|
-
receipt: input.receipt
|
|
568086
|
+
receipt: input.receipt,
|
|
568087
|
+
progressClass: input.progressClass
|
|
568079
568088
|
});
|
|
568080
568089
|
}
|
|
568081
568090
|
function addCompletionClaims(ledger, claims) {
|
|
@@ -568199,6 +568208,9 @@ function classifyCompletionProgress(entry) {
|
|
|
568199
568208
|
if (entry.kind === "file_change" || entry.role === "mutation") {
|
|
568200
568209
|
return "work_product";
|
|
568201
568210
|
}
|
|
568211
|
+
if (/^(file_write|file_edit|file_patch|batch_edit)$/.test(entry.toolName ?? "")) {
|
|
568212
|
+
return "work_product";
|
|
568213
|
+
}
|
|
568202
568214
|
return "observation";
|
|
568203
568215
|
}
|
|
568204
568216
|
function isMutationEvidence(entry) {
|
|
@@ -568233,7 +568245,11 @@ function isVerificationInvalidatingMutation(entry) {
|
|
|
568233
568245
|
return entry.verificationImpact !== "neutral";
|
|
568234
568246
|
}
|
|
568235
568247
|
function isSuccessfulVerificationEvidence(entry) {
|
|
568236
|
-
|
|
568248
|
+
if (entry.role !== "verification" || entry.success !== true)
|
|
568249
|
+
return false;
|
|
568250
|
+
if (!entry.receipt)
|
|
568251
|
+
return true;
|
|
568252
|
+
return entry.receipt.schema === "omnius.command-evidence-receipt.v1" && Boolean(entry.receipt.canonicalCommand.trim()) && Boolean(entry.receipt.cwd.trim()) && entry.receipt.exitCode === 0 && !entry.receipt.timedOut;
|
|
568237
568253
|
}
|
|
568238
568254
|
function isFailedVerificationEvidence(entry) {
|
|
568239
568255
|
return entry.role === "verification" && entry.success === false;
|
|
@@ -571548,6 +571564,13 @@ function buildReferenceContractBundle(input) {
|
|
|
571548
571564
|
});
|
|
571549
571565
|
}
|
|
571550
571566
|
}
|
|
571567
|
+
if (input.includeDeliverySurface && !candidates.some((candidate) => candidate.id === "delivery_surface")) {
|
|
571568
|
+
candidates.push({
|
|
571569
|
+
id: "delivery_surface",
|
|
571570
|
+
phase: input.phase,
|
|
571571
|
+
reason: "workspace_delivery_coverage_manifest"
|
|
571572
|
+
});
|
|
571573
|
+
}
|
|
571551
571574
|
if (input.includeExplicit !== false) {
|
|
571552
571575
|
for (const id2 of explicitContractIds(input.explicitModules)) {
|
|
571553
571576
|
candidates.push({
|
|
@@ -571665,11 +571688,53 @@ var init_reference_contracts = __esm({
|
|
|
571665
571688
|
}
|
|
571666
571689
|
});
|
|
571667
571690
|
|
|
571691
|
+
// packages/orchestrator/dist/phase-skill-guidance.js
|
|
571692
|
+
function buildPhaseSkillGuidance(input) {
|
|
571693
|
+
const query = [
|
|
571694
|
+
`Active lifecycle phase: ${input.phase}.`,
|
|
571695
|
+
`Phase focus: ${PHASE_FOCUS[input.phase]}.`,
|
|
571696
|
+
`Current user goal: ${input.goal}`,
|
|
571697
|
+
input.currentStep ? `Current work item: ${input.currentStep}` : ""
|
|
571698
|
+
].filter(Boolean).join("\n");
|
|
571699
|
+
const pack = buildEphemeralSkillPack(input.skills ?? discoverSkills(input.repoRoot), {
|
|
571700
|
+
task: query,
|
|
571701
|
+
modelTier: input.modelTier,
|
|
571702
|
+
// Phase support must leave the evidence and current task dominant.
|
|
571703
|
+
limit: input.modelTier === "small" ? 2 : 3
|
|
571704
|
+
});
|
|
571705
|
+
if (!pack)
|
|
571706
|
+
return "";
|
|
571707
|
+
return [
|
|
571708
|
+
"[PHASE SKILL GUIDANCE]",
|
|
571709
|
+
`phase=${input.phase}`,
|
|
571710
|
+
"This is a live manifest selected from installed/project skills for the current phase. Load targeted guidance only when it materially helps the next action.",
|
|
571711
|
+
pack,
|
|
571712
|
+
"[/PHASE SKILL GUIDANCE]"
|
|
571713
|
+
].join("\n");
|
|
571714
|
+
}
|
|
571715
|
+
var PHASE_FOCUS;
|
|
571716
|
+
var init_phase_skill_guidance = __esm({
|
|
571717
|
+
"packages/orchestrator/dist/phase-skill-guidance.js"() {
|
|
571718
|
+
"use strict";
|
|
571719
|
+
init_dist5();
|
|
571720
|
+
PHASE_FOCUS = {
|
|
571721
|
+
explore: "repository discovery requirements analysis source inspection provenance capability boundary falsification",
|
|
571722
|
+
plan: "requirements planning architecture design acceptance criteria claim evidence risk analysis",
|
|
571723
|
+
implement: "implementation code change editing debugging tests integration safety",
|
|
571724
|
+
verify: "verification validation acceptance tests evidence receipts release documentation consistency",
|
|
571725
|
+
mixed: "implementation verification testing code review evidence"
|
|
571726
|
+
};
|
|
571727
|
+
}
|
|
571728
|
+
});
|
|
571729
|
+
|
|
571668
571730
|
// packages/orchestrator/dist/deliveryCoverage.js
|
|
571669
571731
|
import { createHash as createHash30 } from "node:crypto";
|
|
571670
571732
|
import { existsSync as existsSync90, readFileSync as readFileSync70 } from "node:fs";
|
|
571671
571733
|
import { join as join102 } from "node:path";
|
|
571672
571734
|
import { z as z17 } from "zod";
|
|
571735
|
+
function canonicalPath(path16) {
|
|
571736
|
+
return String(path16 ?? "").trim().replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/+/g, "/");
|
|
571737
|
+
}
|
|
571673
571738
|
function duplicates(values) {
|
|
571674
571739
|
const seen = /* @__PURE__ */ new Set();
|
|
571675
571740
|
const out = /* @__PURE__ */ new Set();
|
|
@@ -571715,17 +571780,25 @@ function normalizeEvidence2(availableEvidence) {
|
|
|
571715
571780
|
}
|
|
571716
571781
|
return evidence;
|
|
571717
571782
|
}
|
|
571718
|
-
function evaluateDeliveryCoverage(manifest, availableEvidenceIds = []) {
|
|
571783
|
+
function evaluateDeliveryCoverage(manifest, availableEvidenceIds = [], sourceObservations = []) {
|
|
571719
571784
|
const gaps = [];
|
|
571720
571785
|
const sourceById = new Map(manifest.sources.map((item) => [item.id, item]));
|
|
571721
571786
|
const contractById = new Map(manifest.contracts.map((item) => [item.id, item]));
|
|
571722
571787
|
const acceptanceById = new Map(manifest.acceptance.map((item) => [item.id, item]));
|
|
571788
|
+
const inspectionById = new Map(manifest.inspections.map((item) => [item.id, item]));
|
|
571789
|
+
const contradictionById = new Map(manifest.contradictionChecks.map((item) => [item.id, item]));
|
|
571723
571790
|
const availableEvidence = normalizeEvidence2(availableEvidenceIds);
|
|
571724
571791
|
const available = new Set(availableEvidence.map((item) => item.id));
|
|
571792
|
+
const observations = [...sourceObservations].map((item) => ({
|
|
571793
|
+
...item,
|
|
571794
|
+
path: canonicalPath(item.path)
|
|
571795
|
+
}));
|
|
571725
571796
|
for (const id2 of duplicates([
|
|
571726
571797
|
...manifest.sources.map((item) => item.id),
|
|
571727
571798
|
...manifest.contracts.map((item) => item.id),
|
|
571728
571799
|
...manifest.acceptance.map((item) => item.id),
|
|
571800
|
+
...manifest.inspections.map((item) => item.id),
|
|
571801
|
+
...manifest.contradictionChecks.map((item) => item.id),
|
|
571729
571802
|
...manifest.claims.map((item) => item.id)
|
|
571730
571803
|
])) {
|
|
571731
571804
|
gaps.push({ claimId: id2, code: "duplicate_id", detail: `Duplicate manifest id '${id2}'.` });
|
|
@@ -571746,6 +571819,7 @@ function evaluateDeliveryCoverage(manifest, availableEvidenceIds = []) {
|
|
|
571746
571819
|
}
|
|
571747
571820
|
}
|
|
571748
571821
|
const claimStates = manifest.claims.map((claim) => {
|
|
571822
|
+
const gapsBeforeClaim = gaps.length;
|
|
571749
571823
|
for (const sourceId of claim.sourceIds) {
|
|
571750
571824
|
if (!sourceById.has(sourceId)) {
|
|
571751
571825
|
gaps.push({ claimId: claim.id, code: "unknown_source", detail: `Claim references unknown source '${sourceId}'.` });
|
|
@@ -571799,6 +571873,57 @@ function evaluateDeliveryCoverage(manifest, availableEvidenceIds = []) {
|
|
|
571799
571873
|
if (claim.state === "blocked" && !claim.blockedReason) {
|
|
571800
571874
|
gaps.push({ claimId: claim.id, code: "blocked_reason_required", detail: "Blocked claims require a concrete blockedReason." });
|
|
571801
571875
|
}
|
|
571876
|
+
if (manifest.schemaVersion >= 2 && claim.state !== "blocked" && (claim.requiredInspectionIds.length === 0 || claim.requiredContradictionCheckIds.length === 0)) {
|
|
571877
|
+
gaps.push({
|
|
571878
|
+
claimId: claim.id,
|
|
571879
|
+
code: "missing_inspection_contract",
|
|
571880
|
+
detail: "V2 non-blocked claims must name source inspections and contradiction checks."
|
|
571881
|
+
});
|
|
571882
|
+
}
|
|
571883
|
+
const missingInspectionIds = [];
|
|
571884
|
+
for (const inspectionId of claim.requiredInspectionIds) {
|
|
571885
|
+
const inspection = inspectionById.get(inspectionId);
|
|
571886
|
+
if (!inspection) {
|
|
571887
|
+
missingInspectionIds.push(inspectionId);
|
|
571888
|
+
gaps.push({ claimId: claim.id, code: "unknown_inspection", detail: `Claim references unknown inspection '${inspectionId}'.` });
|
|
571889
|
+
continue;
|
|
571890
|
+
}
|
|
571891
|
+
const unsatisfiedPaths = inspection.targetPaths.filter((path16) => {
|
|
571892
|
+
const normalizedPath = canonicalPath(path16);
|
|
571893
|
+
return !observations.some((observation) => observation.path === normalizedPath && observation.stale !== true && observation.fidelity === "full" && Boolean(observation.contentHash));
|
|
571894
|
+
});
|
|
571895
|
+
if (unsatisfiedPaths.length > 0) {
|
|
571896
|
+
missingInspectionIds.push(inspectionId);
|
|
571897
|
+
const observedButUnusable = unsatisfiedPaths.some((path16) => observations.some((observation) => observation.path === canonicalPath(path16)));
|
|
571898
|
+
gaps.push({
|
|
571899
|
+
claimId: claim.id,
|
|
571900
|
+
code: observedButUnusable ? "stale_inspection" : "missing_inspection",
|
|
571901
|
+
detail: `${inspection.boundary} inspection '${inspectionId}' needs fresh full hashed read(s): ${unsatisfiedPaths.join(", ")}.`
|
|
571902
|
+
});
|
|
571903
|
+
}
|
|
571904
|
+
}
|
|
571905
|
+
const missingContradictionCheckIds = [];
|
|
571906
|
+
for (const checkId of claim.requiredContradictionCheckIds) {
|
|
571907
|
+
const check = contradictionById.get(checkId);
|
|
571908
|
+
if (!check) {
|
|
571909
|
+
missingContradictionCheckIds.push(checkId);
|
|
571910
|
+
gaps.push({ claimId: claim.id, code: "unknown_contradiction_check", detail: `Claim references unknown contradiction check '${checkId}'.` });
|
|
571911
|
+
continue;
|
|
571912
|
+
}
|
|
571913
|
+
const unresolvedInspectionIds = check.inspectionIds.filter((id2) => {
|
|
571914
|
+
if (!claim.requiredInspectionIds.includes(id2))
|
|
571915
|
+
return true;
|
|
571916
|
+
return missingInspectionIds.includes(id2);
|
|
571917
|
+
});
|
|
571918
|
+
if (unresolvedInspectionIds.length > 0) {
|
|
571919
|
+
missingContradictionCheckIds.push(checkId);
|
|
571920
|
+
gaps.push({
|
|
571921
|
+
claimId: claim.id,
|
|
571922
|
+
code: "missing_contradiction_check",
|
|
571923
|
+
detail: `Contradiction check '${checkId}' (${check.question}) lacks fresh inspection evidence: ${unresolvedInspectionIds.join(", ")}.`
|
|
571924
|
+
});
|
|
571925
|
+
}
|
|
571926
|
+
}
|
|
571802
571927
|
const required = requiredLayers(claim.state);
|
|
571803
571928
|
const selected = claim.requiredAcceptanceIds.map((id2) => acceptanceById.get(id2)).filter((item) => Boolean(item));
|
|
571804
571929
|
const missingAcceptanceIds = required.filter((layer) => !selected.some((item) => item.layer === layer && item.requiredFor.includes(claim.state)));
|
|
@@ -571829,11 +571954,16 @@ function evaluateDeliveryCoverage(manifest, availableEvidenceIds = []) {
|
|
|
571829
571954
|
gaps.push({ claimId: claim.id, code: "missing_evidence", detail: `Evidence receipt(s) are not present in this run: ${missingEvidence.join(", ")}.` });
|
|
571830
571955
|
}
|
|
571831
571956
|
}
|
|
571957
|
+
const claimHasGap = gaps.slice(gapsBeforeClaim).some((gap) => gap.claimId === claim.id);
|
|
571958
|
+
const attainedState = claim.state === "blocked" ? "blocked" : claimHasGap ? "unproven" : claim.state;
|
|
571832
571959
|
return {
|
|
571833
571960
|
id: claim.id,
|
|
571834
571961
|
state: claim.state,
|
|
571962
|
+
attainedState,
|
|
571835
571963
|
evidenceIds: claim.evidenceIds,
|
|
571836
|
-
missingAcceptanceIds
|
|
571964
|
+
missingAcceptanceIds,
|
|
571965
|
+
missingInspectionIds,
|
|
571966
|
+
missingContradictionCheckIds
|
|
571837
571967
|
};
|
|
571838
571968
|
});
|
|
571839
571969
|
return {
|
|
@@ -571861,7 +571991,7 @@ function renderDeliveryCoverageState(evaluation, sourcePath) {
|
|
|
571861
571991
|
`sha256=${evaluation.manifestHash}`,
|
|
571862
571992
|
`completion_ready=${evaluation.completionReady}`,
|
|
571863
571993
|
"claims:",
|
|
571864
|
-
...evaluation.claimStates.slice(0, 12).map((claim) => `- id=${claim.id} state=${claim.state} evidence=${claim.evidenceIds.join(",") || "none"} missing_acceptance=${claim.missingAcceptanceIds.join(",") || "none"}`),
|
|
571994
|
+
...evaluation.claimStates.slice(0, 12).map((claim) => `- id=${claim.id} state=${claim.state} attained=${claim.attainedState} evidence=${claim.evidenceIds.join(",") || "none"} missing_inspection=${claim.missingInspectionIds.join(",") || "none"} missing_contradiction=${claim.missingContradictionCheckIds.join(",") || "none"} missing_acceptance=${claim.missingAcceptanceIds.join(",") || "none"}`),
|
|
571865
571995
|
"gaps:",
|
|
571866
571996
|
...evaluation.gaps.length > 0 ? evaluation.gaps.slice(0, 12).map((gap) => `- [${gap.code}] ${gap.claimId}: ${gap.detail}`) : ["- none"],
|
|
571867
571997
|
"Treat this as delivery truth, not a recovery directive. A blocked or simulation-only claim must remain labeled at that state.",
|
|
@@ -571869,7 +571999,7 @@ function renderDeliveryCoverageState(evaluation, sourcePath) {
|
|
|
571869
571999
|
];
|
|
571870
572000
|
return lines.join("\n");
|
|
571871
572001
|
}
|
|
571872
|
-
var deliveryRealityStates, acceptanceLayers, sourceSchema, contractSchema, acceptanceSchema, subjectSchema, claimSchema, deliveryCoverageManifestSchema;
|
|
572002
|
+
var deliveryRealityStates, acceptanceLayers, sourceSchema, contractSchema, acceptanceSchema, inspectionSchema, contradictionCheckSchema, subjectSchema, claimSchema, deliveryCoverageManifestSchema;
|
|
571873
572003
|
var init_deliveryCoverage = __esm({
|
|
571874
572004
|
"packages/orchestrator/dist/deliveryCoverage.js"() {
|
|
571875
572005
|
"use strict";
|
|
@@ -571911,6 +572041,17 @@ var init_deliveryCoverage = __esm({
|
|
|
571911
572041
|
verificationCommands: z17.array(z17.string().min(1)).min(1),
|
|
571912
572042
|
safetyInterlock: z17.string().min(1).optional()
|
|
571913
572043
|
});
|
|
572044
|
+
inspectionSchema = z17.object({
|
|
572045
|
+
id: z17.string().min(1),
|
|
572046
|
+
boundary: z17.string().min(1),
|
|
572047
|
+
targetPaths: z17.array(z17.string().min(1)).min(1),
|
|
572048
|
+
proves: z17.string().min(1)
|
|
572049
|
+
});
|
|
572050
|
+
contradictionCheckSchema = z17.object({
|
|
572051
|
+
id: z17.string().min(1),
|
|
572052
|
+
question: z17.string().min(1),
|
|
572053
|
+
inspectionIds: z17.array(z17.string().min(1)).min(1)
|
|
572054
|
+
});
|
|
571914
572055
|
subjectSchema = z17.object({
|
|
571915
572056
|
productSeries: z17.string().min(1),
|
|
571916
572057
|
commands: z17.array(z17.string().min(1)).default([]),
|
|
@@ -571925,13 +572066,21 @@ var init_deliveryCoverage = __esm({
|
|
|
571925
572066
|
sourceIds: z17.array(z17.string().min(1)).min(1),
|
|
571926
572067
|
evidenceIds: z17.array(z17.string().min(1)).default([]),
|
|
571927
572068
|
requiredAcceptanceIds: z17.array(z17.string().min(1)).default([]),
|
|
572069
|
+
/** Source boundaries that must be freshly read before this claim is true. */
|
|
572070
|
+
requiredInspectionIds: z17.array(z17.string().min(1)).default([]),
|
|
572071
|
+
/** Falsification checks that must be grounded in those source inspections. */
|
|
572072
|
+
requiredContradictionCheckIds: z17.array(z17.string().min(1)).default([]),
|
|
571928
572073
|
blockedReason: z17.string().min(1).optional()
|
|
571929
572074
|
});
|
|
571930
572075
|
deliveryCoverageManifestSchema = z17.object({
|
|
571931
|
-
|
|
572076
|
+
// Version 1 remains readable for existing workspaces. Version 2 activates
|
|
572077
|
+
// claim-driven source inspection and falsification gates.
|
|
572078
|
+
schemaVersion: z17.union([z17.literal(1), z17.literal(2)]),
|
|
571932
572079
|
sources: z17.array(sourceSchema),
|
|
571933
572080
|
contracts: z17.array(contractSchema),
|
|
571934
572081
|
acceptance: z17.array(acceptanceSchema),
|
|
572082
|
+
inspections: z17.array(inspectionSchema).default([]),
|
|
572083
|
+
contradictionChecks: z17.array(contradictionCheckSchema).default([]),
|
|
571935
572084
|
claims: z17.array(claimSchema)
|
|
571936
572085
|
});
|
|
571937
572086
|
}
|
|
@@ -575540,6 +575689,8 @@ function buildTrajectoryCheckpoint(input) {
|
|
|
575540
575689
|
} else if (focus) {
|
|
575541
575690
|
assessment = "recovery_required";
|
|
575542
575691
|
const focusDiagnostic = extractFocusNextAction(focus);
|
|
575692
|
+
if (focusDiagnostic)
|
|
575693
|
+
nextAction = focusDiagnostic;
|
|
575543
575694
|
successEvidence = focusDiagnostic ? `Active controller directive remains unresolved: ${focusDiagnostic}` : "An active controller directive is unresolved; its evidence is recorded separately.";
|
|
575544
575695
|
} else if (hasRecentFailure && !fullWriteRecoveredByMutation) {
|
|
575545
575696
|
assessment = "recovery_required";
|
|
@@ -576262,7 +576413,7 @@ function extractAnchorsFromMessages(messages2, turn, workspaceRoot) {
|
|
|
576262
576413
|
continue;
|
|
576263
576414
|
if (msg.role === "tool" || msg.role === "assistant") {
|
|
576264
576415
|
const matches = content.match(FILE_PATH_RE) ?? [];
|
|
576265
|
-
const distinctPaths = Array.from(new Set(matches.filter((p2) => isFileAnchorCandidate(p2, workspaceRoot)))).slice(0, 5);
|
|
576416
|
+
const distinctPaths = Array.from(new Set(matches.map((p2) => p2.trim().replace(/^['"`]+|['"`,.;:)\]]+$/g, "")).filter((p2) => isFileAnchorCandidate(p2, workspaceRoot)))).slice(0, 5);
|
|
576266
576417
|
for (const p2 of distinctPaths) {
|
|
576267
576418
|
const summary = `file: ${p2}`;
|
|
576268
576419
|
if (seenSummaries.has(summary))
|
|
@@ -591485,6 +591636,7 @@ var init_agenticRunner = __esm({
|
|
|
591485
591636
|
init_personality();
|
|
591486
591637
|
init_promptLoader();
|
|
591487
591638
|
init_reference_contracts();
|
|
591639
|
+
init_phase_skill_guidance();
|
|
591488
591640
|
init_deliveryCoverage();
|
|
591489
591641
|
init_critic();
|
|
591490
591642
|
init_reflection();
|
|
@@ -592143,6 +592295,10 @@ var init_agenticRunner = __esm({
|
|
|
592143
592295
|
_toolLastUsedTurn = /* @__PURE__ */ new Map();
|
|
592144
592296
|
_ephemeralSkillPackContext = "";
|
|
592145
592297
|
_stickyDynamicContext = "";
|
|
592298
|
+
// Successful PFV/SSMA analyses are controller facts, not prompt fragments.
|
|
592299
|
+
// Keep one expiring delta so a capable model sees the current diagnosis and
|
|
592300
|
+
// evidence handle without inheriting an archive of REG directives.
|
|
592301
|
+
_recoveryControllerDelta = null;
|
|
592146
592302
|
// Phase 1 — Context Tree. Tracks current phase + per-phase anchors so
|
|
592147
592303
|
// compactMessages can summarize-by-phase and Phase 6 can surface anchors
|
|
592148
592304
|
// by keyword. Initialized lazily in run() because the system-prompt hash
|
|
@@ -592978,6 +593134,17 @@ ${parts.join("\n")}
|
|
|
592978
593134
|
lines.push(`declared_next_action=${ts.nextAction.replace(/\s+/g, " ").slice(0, 220)}`);
|
|
592979
593135
|
}
|
|
592980
593136
|
lines.push(`progress_anchor=completed_steps:${ts.completedSteps.length} failed_approaches:${ts.failedApproaches.length} modified_files:${ts.modifiedFiles.size} tool_calls:${ts.toolCallCount}`);
|
|
593137
|
+
const recoveryDelta = this._recoveryControllerDelta;
|
|
593138
|
+
if (recoveryDelta && recoveryDelta.expiresAtTurn >= turn) {
|
|
593139
|
+
lines.push(`recovery_delta=${recoveryDelta.source} evidence=${recoveryDelta.evidenceHandle}`);
|
|
593140
|
+
lines.push(`recovery_diagnosis=${recoveryDelta.diagnosis}`);
|
|
593141
|
+
lines.push(`recovery_next_action=${recoveryDelta.nextAction}`);
|
|
593142
|
+
if (recoveryDelta.verification) {
|
|
593143
|
+
lines.push(`recovery_exit_evidence=${recoveryDelta.verification}`);
|
|
593144
|
+
}
|
|
593145
|
+
} else if (recoveryDelta) {
|
|
593146
|
+
this._recoveryControllerDelta = null;
|
|
593147
|
+
}
|
|
592981
593148
|
if (ts.completedSteps.length > 0) {
|
|
592982
593149
|
lines.push(`recent_completed=${ts.completedSteps.slice(-3).join(" | ").replace(/\s+/g, " ").slice(0, 420)}`);
|
|
592983
593150
|
}
|
|
@@ -593029,6 +593196,24 @@ ${parts.join("\n")}
|
|
|
593029
593196
|
lines.push(this._todoWriteAvailable() ? "not_progress=repeat unchanged todo_write; repeat broad discovery already represented in this frame; keep discovery active after a real mutation" : "not_progress=repeat broad discovery already represented in this frame; keep discovery active after a real mutation");
|
|
593030
593197
|
return lines.join("\n");
|
|
593031
593198
|
}
|
|
593199
|
+
_recordRecoveryControllerDelta(input) {
|
|
593200
|
+
const diagnosis = String(input.diagnosis ?? "").replace(/\s+/g, " ").trim().slice(0, 320);
|
|
593201
|
+
const nextAction = String(input.nextAction ?? "").replace(/\s+/g, " ").trim().slice(0, 320);
|
|
593202
|
+
if (!diagnosis || !nextAction)
|
|
593203
|
+
return;
|
|
593204
|
+
this._recoveryControllerDelta = {
|
|
593205
|
+
source: input.source,
|
|
593206
|
+
evidenceHandle: `${input.source}@turn-${input.turn}`,
|
|
593207
|
+
diagnosis,
|
|
593208
|
+
nextAction,
|
|
593209
|
+
verification: String(input.verification ?? "").replace(/\s+/g, " ").trim().slice(0, 260),
|
|
593210
|
+
expectedTool: input.expectedTool,
|
|
593211
|
+
// A delta is a live controller state, not an instruction archive. It
|
|
593212
|
+
// naturally expires unless the proposed action is attempted first.
|
|
593213
|
+
expiresAtTurn: input.turn + 4
|
|
593214
|
+
};
|
|
593215
|
+
this._trajectoryDirtyCauses.add(`recovery_${input.source}`);
|
|
593216
|
+
}
|
|
593032
593217
|
_workboardTodoCardForPaths(snapshot, paths) {
|
|
593033
593218
|
const targets = [
|
|
593034
593219
|
...new Set(paths.map((path16) => this._normalizeEvidencePath(path16)))
|
|
@@ -593476,16 +593661,29 @@ evidence=${record.evidenceIds.join(",") || "none"}`
|
|
|
593476
593661
|
const loaded = loadDeliveryCoverageManifest(this.authoritativeWorkingDirectory());
|
|
593477
593662
|
if (!loaded)
|
|
593478
593663
|
return null;
|
|
593664
|
+
for (const entry of this._evidenceLedger.snapshot(200)) {
|
|
593665
|
+
this._evidenceLedger.validateFreshness(entry.path, _pathResolve(this.authoritativeWorkingDirectory(), entry.path));
|
|
593666
|
+
}
|
|
593479
593667
|
const evidence = this._completionLedger?.evidence.map((entry) => ({
|
|
593480
593668
|
id: entry.id,
|
|
593481
593669
|
success: entry.success,
|
|
593482
593670
|
receipt: entry.receipt
|
|
593483
593671
|
})) ?? [];
|
|
593484
|
-
const
|
|
593672
|
+
const sourceObservations = this._evidenceLedger.snapshot(200).map((entry) => ({
|
|
593673
|
+
path: entry.path,
|
|
593674
|
+
contentHash: entry.contentHash,
|
|
593675
|
+
fidelity: entry.fidelity,
|
|
593676
|
+
stale: entry.stale
|
|
593677
|
+
}));
|
|
593678
|
+
const evaluated = evaluateDeliveryCoverage(loaded.manifest, evidence, sourceObservations);
|
|
593679
|
+
const firstInspectionGap = evaluated.gaps.find((gap) => gap.code === "missing_inspection" || gap.code === "stale_inspection" || gap.code === "missing_contradiction_check");
|
|
593485
593680
|
return {
|
|
593486
593681
|
rendered: renderDeliveryCoverageState(evaluated, loaded.path),
|
|
593487
593682
|
gaps: evaluated.gaps.map((gap) => `[${gap.code}] ${gap.claimId}: ${gap.detail}`),
|
|
593488
|
-
completionReady: evaluated.completionReady
|
|
593683
|
+
completionReady: evaluated.completionReady,
|
|
593684
|
+
...firstInspectionGap ? { nextInspection: firstInspectionGap.detail } : {},
|
|
593685
|
+
sourcePath: loaded.path,
|
|
593686
|
+
evaluation: evaluated
|
|
593489
593687
|
};
|
|
593490
593688
|
}
|
|
593491
593689
|
_modelCapabilityProfile() {
|
|
@@ -593517,6 +593715,24 @@ evidence=${record.evidenceIds.join(",") || "none"}`
|
|
|
593517
593715
|
this._completionLedger = {
|
|
593518
593716
|
...this._completionLedger,
|
|
593519
593717
|
unresolved: [...retained, ...unresolved],
|
|
593718
|
+
deliveryCoverage: {
|
|
593719
|
+
manifestHash: coverage.evaluation.manifestHash,
|
|
593720
|
+
sourcePath: coverage.sourcePath,
|
|
593721
|
+
evaluatedAtIso: (/* @__PURE__ */ new Date()).toISOString(),
|
|
593722
|
+
claims: coverage.evaluation.claimStates.map((claim) => ({
|
|
593723
|
+
id: claim.id,
|
|
593724
|
+
state: claim.state,
|
|
593725
|
+
attainedState: claim.attainedState,
|
|
593726
|
+
missingInspectionIds: [...claim.missingInspectionIds],
|
|
593727
|
+
missingContradictionCheckIds: [...claim.missingContradictionCheckIds],
|
|
593728
|
+
missingAcceptanceIds: [...claim.missingAcceptanceIds]
|
|
593729
|
+
})),
|
|
593730
|
+
gaps: coverage.evaluation.gaps.map((gap) => ({
|
|
593731
|
+
claimId: gap.claimId,
|
|
593732
|
+
code: gap.code,
|
|
593733
|
+
detail: gap.detail
|
|
593734
|
+
}))
|
|
593735
|
+
},
|
|
593520
593736
|
status: coverage.completionReady && unresolved.length === 0 ? this._completionLedger.status : "incomplete_verification",
|
|
593521
593737
|
updatedAtIso: (/* @__PURE__ */ new Date()).toISOString()
|
|
593522
593738
|
};
|
|
@@ -594271,10 +594487,10 @@ ${read3.content}`;
|
|
|
594271
594487
|
if (!branchDerived && !partialMaterialization && path16) {
|
|
594272
594488
|
try {
|
|
594273
594489
|
const canonicalBody = input.result.output || input.output;
|
|
594274
|
-
const
|
|
594490
|
+
const canonicalPath2 = this._normalizeEvidencePath(path16);
|
|
594275
594491
|
const sourceRevision = typeof input.result.beforeHash === "string" ? input.result.beforeHash : _createHash("sha256").update(canonicalBody).digest("hex");
|
|
594276
594492
|
const stored = this._artifactStore().put({
|
|
594277
|
-
path:
|
|
594493
|
+
path: canonicalPath2,
|
|
594278
594494
|
revision: sourceRevision,
|
|
594279
594495
|
content: canonicalBody,
|
|
594280
594496
|
ranges: [{
|
|
@@ -594314,13 +594530,13 @@ ${read3.content}`;
|
|
|
594314
594530
|
ledger.linkDependency({ sourceRecordId: artifact.id, targetRecordId: result.id, relation: "derived_from", requiredForActiveWork: true });
|
|
594315
594531
|
ledger.linkDependency({ sourceRecordId: action.id, targetRecordId: artifact.id, relation: "requires", requiredForActiveWork: true });
|
|
594316
594532
|
if (!branchDerived && !partialMaterialization && path16) {
|
|
594317
|
-
const
|
|
594318
|
-
const previous = this._contextMemoryArtifactByPath.get(
|
|
594533
|
+
const canonicalPath2 = this._normalizeEvidencePath(path16);
|
|
594534
|
+
const previous = this._contextMemoryArtifactByPath.get(canonicalPath2);
|
|
594319
594535
|
const currentHash = typeof input.result.beforeHash === "string" ? input.result.beforeHash : void 0;
|
|
594320
594536
|
if (previous && previous.epoch === epoch && previous.contentHash && currentHash && previous.contentHash !== currentHash) {
|
|
594321
594537
|
ledger.supersedeArtifact(previous.recordId, artifact.id);
|
|
594322
594538
|
}
|
|
594323
|
-
this._contextMemoryArtifactByPath.set(
|
|
594539
|
+
this._contextMemoryArtifactByPath.set(canonicalPath2, {
|
|
594324
594540
|
recordId: artifact.id,
|
|
594325
594541
|
contentHash: currentHash,
|
|
594326
594542
|
...canonicalArtifactReference ? { artifactReference: canonicalArtifactReference } : {},
|
|
@@ -600124,7 +600340,12 @@ ${String(concreteGoal).replace(/\s+/g, " ").trim().slice(0, 1200)}` : null
|
|
|
600124
600340
|
const gitBlock = this._renderGitProgressBlock(turn);
|
|
600125
600341
|
const failureBlock = null;
|
|
600126
600342
|
const churnBlock = null;
|
|
600127
|
-
const
|
|
600343
|
+
const focusDirective = this._focusSupervisor?.snapshot().directive;
|
|
600344
|
+
const focusBlock = focusDirective ? [
|
|
600345
|
+
`required_next_action=${focusDirective.requiredNextAction}`,
|
|
600346
|
+
`reason=${focusDirective.reason}`,
|
|
600347
|
+
`state=${focusDirective.state}`
|
|
600348
|
+
].join("\n") : null;
|
|
600128
600349
|
const actionContractBlock = this._renderNextActionContract(turn);
|
|
600129
600350
|
const deliveryCoverageBlock = this._deliveryCoverageState()?.rendered ?? null;
|
|
600130
600351
|
const referenceContractPhase = this._contextTree?.getCurrentPhase() ?? "mixed";
|
|
@@ -600133,7 +600354,15 @@ ${String(concreteGoal).replace(/\s+/g, " ").trim().slice(0, 1200)}` : null
|
|
|
600133
600354
|
tier: this.options.modelTier ?? "large",
|
|
600134
600355
|
includeCore: false,
|
|
600135
600356
|
includePhase: true,
|
|
600136
|
-
includeExplicit: false
|
|
600357
|
+
includeExplicit: false,
|
|
600358
|
+
includeDeliverySurface: Boolean(deliveryCoverageBlock)
|
|
600359
|
+
});
|
|
600360
|
+
const phaseSkillGuidance = buildPhaseSkillGuidance({
|
|
600361
|
+
repoRoot: this.authoritativeWorkingDirectory(),
|
|
600362
|
+
phase: referenceContractPhase,
|
|
600363
|
+
goal: concreteGoal,
|
|
600364
|
+
currentStep: this._taskState.currentStep,
|
|
600365
|
+
modelTier: this.options.modelTier ?? "large"
|
|
600137
600366
|
});
|
|
600138
600367
|
const trajectoryCheckpoint = await this._refreshTrajectoryCheckpoint(turn, focusBlock, [
|
|
600139
600368
|
workspaceTreeBlock,
|
|
@@ -600242,6 +600471,15 @@ ${String(concreteGoal).replace(/\s+/g, " ").trim().slice(0, 1200)}` : null
|
|
|
600242
600471
|
contractIds: phaseContracts.contracts.map((contract) => contract.id)
|
|
600243
600472
|
}
|
|
600244
600473
|
}),
|
|
600474
|
+
signalFromBlock("runtime_guidance", "turn.phase-skills", phaseSkillGuidance, {
|
|
600475
|
+
id: "phase-skills",
|
|
600476
|
+
dedupeKey: "turn.phase-skills",
|
|
600477
|
+
semanticKey: "context.phase-skills",
|
|
600478
|
+
priority: PRIORITY.RUNTIME_GUIDANCE - 1,
|
|
600479
|
+
createdTurn: turn,
|
|
600480
|
+
ttlTurns: 1,
|
|
600481
|
+
metadata: { phase: referenceContractPhase }
|
|
600482
|
+
}),
|
|
600245
600483
|
signalFromBlock("task_state", "turn.todos", todoBlock, {
|
|
600246
600484
|
id: "todo-state",
|
|
600247
600485
|
dedupeKey: "turn.todos",
|
|
@@ -600414,6 +600652,10 @@ ${String(concreteGoal).replace(/\s+/g, " ").trim().slice(0, 1200)}` : null
|
|
|
600414
600652
|
* transition (so the primary loop can reset per-phase tool budgets) or null.
|
|
600415
600653
|
*/
|
|
600416
600654
|
_advanceContextTreeOnToolCall(toolName, argsKey, turn, messages2) {
|
|
600655
|
+
if (this._recoveryControllerDelta?.expectedTool === toolName) {
|
|
600656
|
+
this._recoveryControllerDelta = null;
|
|
600657
|
+
this._trajectoryDirtyCauses.add("recovery_action_attempted");
|
|
600658
|
+
}
|
|
600417
600659
|
if (!this._contextTree)
|
|
600418
600660
|
return null;
|
|
600419
600661
|
this._contextTree.observeToolCall(toolName, argsKey, turn);
|
|
@@ -601704,14 +601946,16 @@ ${notice}`;
|
|
|
601704
601946
|
* protocol correctness; only stale assistant-visible planning prose changes.
|
|
601705
601947
|
*/
|
|
601706
601948
|
_retireLinkedAssistantReadIntents(messages2) {
|
|
601707
|
-
if (!this._legacyModelVisibleCompactionAllowed())
|
|
601708
|
-
return;
|
|
601709
601949
|
const resolvedToolCallIds = new Set(messages2.filter((message2) => message2.role === "tool" && message2.tool_call_id).map((message2) => message2.tool_call_id));
|
|
601710
601950
|
for (const message2 of messages2) {
|
|
601711
601951
|
if (message2.role !== "assistant" || typeof message2.content !== "string" || !Array.isArray(message2.tool_calls) || !message2.tool_calls.some((call) => resolvedToolCallIds.has(call.id)) || !/\b(?:i|we)\s+(?:need|will|should|have)\s+to\s+(?:read|inspect|open)\b/i.test(message2.content)) {
|
|
601712
601952
|
continue;
|
|
601713
601953
|
}
|
|
601714
|
-
|
|
601954
|
+
const index = messages2.indexOf(message2);
|
|
601955
|
+
messages2[index] = {
|
|
601956
|
+
...message2,
|
|
601957
|
+
content: ASSISTANT_READ_INTENT_RETIRED_MARKER
|
|
601958
|
+
};
|
|
601715
601959
|
}
|
|
601716
601960
|
}
|
|
601717
601961
|
_emitSteeringLifecycle(record, reason) {
|
|
@@ -601911,12 +602155,12 @@ ${notice}`;
|
|
|
601911
602155
|
this._emitSteeringLifecycle(record, gatesOldPlan ? `admitted at turn ${turn}; old-plan actions are gated pending structured reconciliation` : `admitted at turn ${turn}; awaiting structured reconciliation`);
|
|
601912
602156
|
}
|
|
601913
602157
|
}
|
|
601914
|
-
_canonicalReadEvidencePayload(
|
|
601915
|
-
const evidence = this._evidenceLedger.get(
|
|
602158
|
+
_canonicalReadEvidencePayload(canonicalPath2, contentHash2) {
|
|
602159
|
+
const evidence = this._evidenceLedger.get(canonicalPath2);
|
|
601916
602160
|
if (evidence && !evidence.stale && evidence.contentHash === contentHash2 && evidence.fidelity === "full" && this._mustHonorExplicitFullFileRead(Buffer.byteLength(evidence.content, "utf8"), evidence.content.split("\n").length, this._branchRoutingContextWindow())) {
|
|
601917
602161
|
return evidence.content;
|
|
601918
602162
|
}
|
|
601919
|
-
const branch = this._branchEvidenceByPath.get(
|
|
602163
|
+
const branch = this._branchEvidenceByPath.get(canonicalPath2);
|
|
601920
602164
|
if (branch && branch.contentHash === contentHash2 && branch.taskEpoch === this._taskEpoch && branch.contractComplete) {
|
|
601921
602165
|
return branch.output;
|
|
601922
602166
|
}
|
|
@@ -602367,17 +602611,17 @@ The steering reconciliation was emitted this turn. Wait for the next model decis
|
|
|
602367
602611
|
}
|
|
602368
602612
|
}
|
|
602369
602613
|
_evictInlineReadArtifacts(messages2, path16, contentHash2, reason) {
|
|
602370
|
-
const
|
|
602614
|
+
const canonicalPath2 = this._normalizeEvidencePath(path16);
|
|
602371
602615
|
let evicted = 0;
|
|
602372
602616
|
for (const [callId, artifact] of this._inlineReadArtifacts) {
|
|
602373
|
-
if (artifact.path !==
|
|
602617
|
+
if (artifact.path !== canonicalPath2 || artifact.contentHash !== contentHash2) {
|
|
602374
602618
|
continue;
|
|
602375
602619
|
}
|
|
602376
602620
|
const message2 = messages2.find((candidate) => candidate.role === "tool" && candidate.tool_call_id === artifact.callId);
|
|
602377
602621
|
if (message2) {
|
|
602378
602622
|
message2.content = [
|
|
602379
602623
|
"[FULL_FILE_READ_EVICTED]",
|
|
602380
|
-
`path=${
|
|
602624
|
+
`path=${canonicalPath2}`,
|
|
602381
602625
|
`sha256=${contentHash2}`,
|
|
602382
602626
|
`reason=${reason}`,
|
|
602383
602627
|
"The full body was deliberately removed after a verified evidence extraction. Use the newer anchored extraction result; re-read only if the file changes or a distinct range is required."
|
|
@@ -602480,15 +602724,15 @@ The steering reconciliation was emitted this turn. Wait for the next model decis
|
|
|
602480
602724
|
purpose: typeof input.args["purpose"] === "string" ? input.args["purpose"] : void 0
|
|
602481
602725
|
});
|
|
602482
602726
|
const contractFingerprint = _createHash("sha256").update(JSON.stringify(branchBrief.discoveryContract ?? branchBrief)).digest("hex").slice(0, 20);
|
|
602483
|
-
const
|
|
602484
|
-
const branchRequestId = `branch:${this._taskEpoch}:${_createHash("sha256").update(`${
|
|
602485
|
-
const cacheKey = `${this._taskEpoch}|${
|
|
602727
|
+
const canonicalPath2 = this._normalizeEvidencePath(rawPath);
|
|
602728
|
+
const branchRequestId = `branch:${this._taskEpoch}:${_createHash("sha256").update(`${canonicalPath2}|${fullHash}|${offset ?? 0}:${limit ?? "EOF"}|${contractFingerprint}`).digest("hex").slice(0, 20)}`;
|
|
602729
|
+
const cacheKey = `${this._taskEpoch}|${canonicalPath2}|${fullHash}|${offset ?? 0}:${limit ?? "EOF"}|${contractFingerprint}`;
|
|
602486
602730
|
const cached2 = this._branchEvidenceCache.get(cacheKey);
|
|
602487
602731
|
if (cached2?.contractComplete) {
|
|
602488
602732
|
const fingerprint2 = this._buildToolFingerprint(input.toolName, input.args);
|
|
602489
602733
|
const rehydrated = this._rehydrateResolvedReadEvidence({
|
|
602490
602734
|
fingerprint: fingerprint2,
|
|
602491
|
-
canonicalPath,
|
|
602735
|
+
canonicalPath: canonicalPath2,
|
|
602492
602736
|
contentHash: fullHash,
|
|
602493
602737
|
payload: cached2.output,
|
|
602494
602738
|
turn: input.turn
|
|
@@ -602501,7 +602745,7 @@ The steering reconciliation was emitted this turn. Wait for the next model decis
|
|
|
602501
602745
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
602502
602746
|
});
|
|
602503
602747
|
if (explicitExtraction) {
|
|
602504
|
-
this._evictInlineReadArtifacts(input.messages,
|
|
602748
|
+
this._evictInlineReadArtifacts(input.messages, canonicalPath2, fullHash, "verified_branch_extract_cache");
|
|
602505
602749
|
}
|
|
602506
602750
|
return {
|
|
602507
602751
|
success: true,
|
|
@@ -602519,7 +602763,7 @@ The steering reconciliation was emitted this turn. Wait for the next model decis
|
|
|
602519
602763
|
schema: "omnius.branch-evidence.v1",
|
|
602520
602764
|
requestId: cached2.requestId,
|
|
602521
602765
|
taskEpoch: this._taskEpoch,
|
|
602522
|
-
path:
|
|
602766
|
+
path: canonicalPath2,
|
|
602523
602767
|
contentHash: fullHash,
|
|
602524
602768
|
sourceRange: {
|
|
602525
602769
|
startLine: startIndex + 1,
|
|
@@ -602587,7 +602831,7 @@ ${suffix}`.slice(0, outputBudgetChars);
|
|
|
602587
602831
|
}
|
|
602588
602832
|
this._branchEvidenceCache.set(cacheKey, {
|
|
602589
602833
|
output,
|
|
602590
|
-
path:
|
|
602834
|
+
path: canonicalPath2,
|
|
602591
602835
|
contentHash: fullHash,
|
|
602592
602836
|
sourceBytes: stat9.size,
|
|
602593
602837
|
createdAt: Date.now(),
|
|
@@ -602602,7 +602846,7 @@ ${suffix}`.slice(0, outputBudgetChars);
|
|
|
602602
602846
|
searchRounds: ev.provenance.searchRounds.length
|
|
602603
602847
|
}
|
|
602604
602848
|
});
|
|
602605
|
-
this._branchEvidenceByPath.set(
|
|
602849
|
+
this._branchEvidenceByPath.set(canonicalPath2, {
|
|
602606
602850
|
output,
|
|
602607
602851
|
contentHash: fullHash,
|
|
602608
602852
|
mtimeMs: stat9.mtimeMs,
|
|
@@ -602612,12 +602856,12 @@ ${suffix}`.slice(0, outputBudgetChars);
|
|
|
602612
602856
|
unresolvedRecoveries: ev.requirementCoverage.filter((coverage) => coverage.status === "unresolved").map((coverage) => `${coverage.id}: ${coverage.recovery ?? "narrow recovery required"}`)
|
|
602613
602857
|
});
|
|
602614
602858
|
if (explicitExtraction) {
|
|
602615
|
-
const evicted = this._evictInlineReadArtifacts(input.messages,
|
|
602859
|
+
const evicted = this._evictInlineReadArtifacts(input.messages, canonicalPath2, fullHash, "verified_branch_extract");
|
|
602616
602860
|
if (evicted > 0) {
|
|
602617
602861
|
this.emit({
|
|
602618
602862
|
type: "status",
|
|
602619
602863
|
toolName: input.toolName,
|
|
602620
|
-
content: `Full read context evicted after verified branch extraction: ${
|
|
602864
|
+
content: `Full read context evicted after verified branch extraction: ${canonicalPath2} sha256=${fullHash.slice(0, 12)} artifacts=${evicted}`,
|
|
602621
602865
|
turn: input.turn,
|
|
602622
602866
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
602623
602867
|
});
|
|
@@ -602647,7 +602891,7 @@ ${suffix}`.slice(0, outputBudgetChars);
|
|
|
602647
602891
|
schema: "omnius.branch-evidence.v1",
|
|
602648
602892
|
requestId: branchRequestId,
|
|
602649
602893
|
taskEpoch: this._taskEpoch,
|
|
602650
|
-
path:
|
|
602894
|
+
path: canonicalPath2,
|
|
602651
602895
|
contentHash: fullHash,
|
|
602652
602896
|
sourceRange: {
|
|
602653
602897
|
startLine: startIndex + 1,
|
|
@@ -603489,6 +603733,7 @@ Respond with the assessment and take the selected evidence-backed action.`;
|
|
|
603489
603733
|
this._toolLastUsedTurn.clear();
|
|
603490
603734
|
this._ephemeralSkillPackContext = "";
|
|
603491
603735
|
this._stickyDynamicContext = "";
|
|
603736
|
+
this._recoveryControllerDelta = null;
|
|
603492
603737
|
this._stableReferenceContracts = [];
|
|
603493
603738
|
this._referenceContractSelections = [];
|
|
603494
603739
|
this._referenceContractPhase = "mixed";
|
|
@@ -603695,6 +603940,7 @@ Respond with the assessment and take the selected evidence-backed action.`;
|
|
|
603695
603940
|
this._memexArchive.clear();
|
|
603696
603941
|
this._todoOutputLedger.clear();
|
|
603697
603942
|
this._sessionId = this.options.sessionId && String(this.options.sessionId) || process.env["OMNIUS_SESSION_ID"] && String(process.env["OMNIUS_SESSION_ID"]) || `session-${Date.now()}`;
|
|
603943
|
+
setTodoSessionId(this._sessionId);
|
|
603698
603944
|
const continuesPriorTask = this._allowImplicitContinuation || this._isContinuationResumeGoal(persistentTaskGoal);
|
|
603699
603945
|
if (!continuesPriorTask) {
|
|
603700
603946
|
this._hidePriorSessionTodosForFreshTask(persistentTaskGoal);
|
|
@@ -604411,6 +604657,34 @@ ${dynamicProjectContext}`
|
|
|
604411
604657
|
messages2.push({ role: "system", content: feedback });
|
|
604412
604658
|
return true;
|
|
604413
604659
|
};
|
|
604660
|
+
const holdDeliveryCoverageTaskComplete = (turn) => {
|
|
604661
|
+
const coverage = this._deliveryCoverageState();
|
|
604662
|
+
if (!coverage || coverage.completionReady)
|
|
604663
|
+
return false;
|
|
604664
|
+
this._reconcileDeliveryCoverageForCompletion();
|
|
604665
|
+
this._saveCompletionLedgerSafe();
|
|
604666
|
+
const gaps = coverage.gaps.slice(0, 6);
|
|
604667
|
+
const feedback = [
|
|
604668
|
+
"[COMPLETION BLOCKED — delivery claim evidence incomplete]",
|
|
604669
|
+
"A declared delivery claim cannot be promoted beyond its current evidence state.",
|
|
604670
|
+
"Open claim deltas:",
|
|
604671
|
+
...gaps.length > 0 ? gaps.map((gap) => ` - ${gap}`) : [" - delivery coverage is not completion-ready"],
|
|
604672
|
+
"",
|
|
604673
|
+
coverage.nextInspection ? `Smallest next observation: ${coverage.nextInspection}` : "Run the missing canonical acceptance command or mark the claim blocked with its real prerequisite.",
|
|
604674
|
+
"Do not replace a missing source inspection with a grep/listing, partial read, or prose summary."
|
|
604675
|
+
].join("\n");
|
|
604676
|
+
lastCompletionGateReason = gaps.join("; ") || "delivery claim evidence incomplete";
|
|
604677
|
+
lastCompletionGateFeedback = feedback;
|
|
604678
|
+
lastCompletionGateCode = "delivery_coverage";
|
|
604679
|
+
messages2.push({ role: "system", content: feedback });
|
|
604680
|
+
this.emit({
|
|
604681
|
+
type: "status",
|
|
604682
|
+
content: `task_complete held by delivery coverage gate: ${lastCompletionGateReason.slice(0, 360)}`,
|
|
604683
|
+
turn,
|
|
604684
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
604685
|
+
});
|
|
604686
|
+
return true;
|
|
604687
|
+
};
|
|
604414
604688
|
const completionHoldEscapeMax = (() => {
|
|
604415
604689
|
const raw = Number(process.env["OMNIUS_COMPLETION_HOLD_MAX"]);
|
|
604416
604690
|
return Number.isFinite(raw) && raw >= 1 ? Math.floor(raw) : 3;
|
|
@@ -604459,7 +604733,7 @@ ${lastCompletionGateFeedback.trim().slice(0, 4e3)}` : ""
|
|
|
604459
604733
|
lastCompletionGateCode = "";
|
|
604460
604734
|
return true;
|
|
604461
604735
|
}
|
|
604462
|
-
const held = holdCompileFixLoopTaskComplete(turn) || holdUnresolvedVerificationTaskComplete(turn) || holdNoProgressTaskComplete(args, turn) || holdProvenanceTaskComplete(args, turn);
|
|
604736
|
+
const held = holdDeliveryCoverageTaskComplete(turn) || holdCompileFixLoopTaskComplete(turn) || holdUnresolvedVerificationTaskComplete(turn) || holdNoProgressTaskComplete(args, turn) || holdProvenanceTaskComplete(args, turn);
|
|
604463
604737
|
if (!held) {
|
|
604464
604738
|
this._completionHoldState.count = 0;
|
|
604465
604739
|
this._completionHoldState.lastKey = "";
|
|
@@ -604471,7 +604745,7 @@ ${lastCompletionGateFeedback.trim().slice(0, 4e3)}` : ""
|
|
|
604471
604745
|
this._focusSupervisor?.markCompletionBlocked({
|
|
604472
604746
|
turn,
|
|
604473
604747
|
reason: lastCompletionGateReason || "completion requested before required evidence was present",
|
|
604474
|
-
requiredNextAction: lastCompletionGateCode === "compile_error_fix_loop" ? "run_verification" : lastCompletionGateCode === "todo_verification" ? "run_verification" : "update_todos"
|
|
604748
|
+
requiredNextAction: lastCompletionGateCode === "delivery_coverage" ? "read_authoritative_target" : lastCompletionGateCode === "compile_error_fix_loop" ? "run_verification" : lastCompletionGateCode === "todo_verification" ? "run_verification" : "update_todos"
|
|
604475
604749
|
});
|
|
604476
604750
|
const focusDirective = this._focusSupervisor?.snapshot().directive;
|
|
604477
604751
|
if (focusDirective) {
|
|
@@ -605314,8 +605588,15 @@ Respond with EXACTLY this structure before your next tool call:
|
|
|
605314
605588
|
},
|
|
605315
605589
|
callable: _smaCallable
|
|
605316
605590
|
}).then((_smaResult) => {
|
|
605317
|
-
if (
|
|
605318
|
-
|
|
605591
|
+
if (!_smaResult.directive.parseFallback) {
|
|
605592
|
+
this._recordRecoveryControllerDelta({
|
|
605593
|
+
source: "stuck_meta",
|
|
605594
|
+
turn,
|
|
605595
|
+
diagnosis: _smaResult.directive.diagnosis,
|
|
605596
|
+
nextAction: `${_smaResult.directive.next_action.tool}: ${_smaResult.directive.next_action.rationale}`,
|
|
605597
|
+
verification: _smaResult.directive.verification,
|
|
605598
|
+
expectedTool: _smaResult.directive.next_action.tool
|
|
605599
|
+
});
|
|
605319
605600
|
this.emit({
|
|
605320
605601
|
type: "status",
|
|
605321
605602
|
content: `REG-49 stuck-meta-analyzer fired at turn ${turn} — diagnosis="${_smaResult.directive.diagnosis.slice(0, 80)}", next=${_smaResult.directive.next_action.tool}, ${_smaResult.durationMs}ms`,
|
|
@@ -605471,8 +605752,15 @@ Respond with EXACTLY this structure before your next tool call:
|
|
|
605471
605752
|
},
|
|
605472
605753
|
callable: _smaCallable50
|
|
605473
605754
|
}).then((_smaResult) => {
|
|
605474
|
-
if (
|
|
605475
|
-
|
|
605755
|
+
if (!_smaResult.directive.parseFallback) {
|
|
605756
|
+
this._recordRecoveryControllerDelta({
|
|
605757
|
+
source: "stuck_meta",
|
|
605758
|
+
turn,
|
|
605759
|
+
diagnosis: _smaResult.directive.diagnosis,
|
|
605760
|
+
nextAction: `${_smaResult.directive.next_action.tool}: ${_smaResult.directive.next_action.rationale}`,
|
|
605761
|
+
verification: _smaResult.directive.verification,
|
|
605762
|
+
expectedTool: _smaResult.directive.next_action.tool
|
|
605763
|
+
});
|
|
605476
605764
|
this.emit({
|
|
605477
605765
|
type: "status",
|
|
605478
605766
|
content: `REG-50 → SSMA fired at turn ${turn} — diagnosis="${_smaResult.directive.diagnosis.slice(0, 80)}", next=${_smaResult.directive.next_action.tool}, ${_smaResult.durationMs}ms`,
|
|
@@ -605612,8 +605900,15 @@ Respond with EXACTLY this structure before your next tool call:
|
|
|
605612
605900
|
},
|
|
605613
605901
|
callable: _pfvCallable
|
|
605614
605902
|
}).then((_pfvResult) => {
|
|
605615
|
-
if (
|
|
605616
|
-
|
|
605903
|
+
if (!_pfvResult.verdict.parseFallback && _pfvResult.verdict.verdict !== "continue") {
|
|
605904
|
+
const frame = _pfvResult.verdict.recommended_frame;
|
|
605905
|
+
this._recordRecoveryControllerDelta({
|
|
605906
|
+
source: "problem_frame",
|
|
605907
|
+
turn,
|
|
605908
|
+
diagnosis: `${_pfvResult.verdict.verdict}: ${_pfvResult.verdict.rationale}`,
|
|
605909
|
+
nextAction: frame?.new_subtask || _pfvResult.verdict.blocker_summary || "Re-evaluate the active task frame against current evidence.",
|
|
605910
|
+
verification: frame?.success_criterion || "Record new evidence for the selected frame."
|
|
605911
|
+
});
|
|
605617
605912
|
this.emit({
|
|
605618
605913
|
type: "status",
|
|
605619
605914
|
content: `REG-51 PFV fired at turn ${turn} — verdict=${_pfvResult.verdict.verdict}, trigger=${_pfvTriggerReason}, ssmaCount=${this._ssmaFiredCount}, ${_pfvResult.durationMs}ms`,
|
|
@@ -607679,7 +607974,8 @@ ${cachedResult}`,
|
|
|
607679
607974
|
const normalizedDispatchName = resolvedTool?.name ?? tc.name;
|
|
607680
607975
|
let branchEvidenceResult = null;
|
|
607681
607976
|
if (normalizedDispatchName === "file_read" && this._fileReadMode(tc.arguments) !== "extract") {
|
|
607682
|
-
const
|
|
607977
|
+
const exactReadFingerprint = this._buildToolFingerprint("file_read", tc.arguments);
|
|
607978
|
+
const exactReadKey = this._resolveReadCoverageFingerprint("file_read", tc.arguments, exactReadFingerprint);
|
|
607683
607979
|
const priorRead = exactFileReadObservations.get(exactReadKey);
|
|
607684
607980
|
if (priorRead) {
|
|
607685
607981
|
const currentRead = this._fileReadDiskIdentity(tc.arguments);
|
|
@@ -610039,8 +610335,15 @@ Only call task_complete when the task is actually complete and the evidence is f
|
|
|
610039
610335
|
},
|
|
610040
610336
|
callable: _smaCallable
|
|
610041
610337
|
}).then((_smaResult) => {
|
|
610042
|
-
if (
|
|
610043
|
-
|
|
610338
|
+
if (!_smaResult.directive.parseFallback) {
|
|
610339
|
+
this._recordRecoveryControllerDelta({
|
|
610340
|
+
source: "stuck_meta",
|
|
610341
|
+
turn,
|
|
610342
|
+
diagnosis: _smaResult.directive.diagnosis,
|
|
610343
|
+
nextAction: `${_smaResult.directive.next_action.tool}: ${_smaResult.directive.next_action.rationale}`,
|
|
610344
|
+
verification: _smaResult.directive.verification,
|
|
610345
|
+
expectedTool: _smaResult.directive.next_action.tool
|
|
610346
|
+
});
|
|
610044
610347
|
this.emit({
|
|
610045
610348
|
type: "status",
|
|
610046
610349
|
content: `REG-49 stuck-meta-analyzer fired (loop-intervention path) at turn ${turn} — diagnosis="${_smaResult.directive.diagnosis.slice(0, 80)}", next=${_smaResult.directive.next_action.tool}, ${_smaResult.durationMs}ms`,
|
|
@@ -614395,15 +614698,15 @@ ${telegramPersonaHead}` : stripped
|
|
|
614395
614698
|
}).slice(0, maxRecoverFiles);
|
|
614396
614699
|
let recoveredTokens = 0;
|
|
614397
614700
|
for (const [filePath, entry] of entries) {
|
|
614398
|
-
const
|
|
614399
|
-
if (alreadyVisiblePaths.has(
|
|
614701
|
+
const canonicalPath2 = this._normalizeEvidencePath(filePath);
|
|
614702
|
+
if (alreadyVisiblePaths.has(canonicalPath2))
|
|
614400
614703
|
continue;
|
|
614401
614704
|
try {
|
|
614402
614705
|
const { readFileSync: readFileSync147 } = await import("node:fs");
|
|
614403
614706
|
const absolutePath = this._absoluteToolPath(filePath);
|
|
614404
614707
|
const content = readFileSync147(absolutePath, "utf8");
|
|
614405
614708
|
const tokenEst = Math.ceil(content.length / 4);
|
|
614406
|
-
const branchNode = this._branchEvidenceByPath.get(
|
|
614709
|
+
const branchNode = this._branchEvidenceByPath.get(canonicalPath2);
|
|
614407
614710
|
const currentMtime = this._statMtimeMsForToolPath(filePath) ?? 0;
|
|
614408
614711
|
const smallCompleteSource = this._mustHonorExplicitFullFileRead(Buffer.byteLength(content, "utf8"), content.split("\n").length, this._branchRoutingContextWindow());
|
|
614409
614712
|
if (smallCompleteSource) {
|
|
@@ -614416,7 +614719,7 @@ ${telegramPersonaHead}` : stripped
|
|
|
614416
614719
|
${content}
|
|
614417
614720
|
</recovered-file>`
|
|
614418
614721
|
});
|
|
614419
|
-
alreadyVisiblePaths.add(
|
|
614722
|
+
alreadyVisiblePaths.add(canonicalPath2);
|
|
614420
614723
|
recoveredFiles.push(filePath);
|
|
614421
614724
|
recoveredTokens += sourceTokens;
|
|
614422
614725
|
continue;
|
|
@@ -614436,7 +614739,7 @@ ${branchNode.output}
|
|
|
614436
614739
|
});
|
|
614437
614740
|
recoveredFiles.push(filePath);
|
|
614438
614741
|
recoveredTokens += nodeTokens;
|
|
614439
|
-
alreadyVisiblePaths.add(
|
|
614742
|
+
alreadyVisiblePaths.add(canonicalPath2);
|
|
614440
614743
|
continue;
|
|
614441
614744
|
}
|
|
614442
614745
|
if (branchNode && !branchNode.contractComplete) {
|
|
@@ -614445,7 +614748,7 @@ ${branchNode.output}
|
|
|
614445
614748
|
if (recoveredTokens + referenceTokens > fileRecoveryBudget)
|
|
614446
614749
|
continue;
|
|
614447
614750
|
result.push({ role: "system", content: partialReference });
|
|
614448
|
-
alreadyVisiblePaths.add(
|
|
614751
|
+
alreadyVisiblePaths.add(canonicalPath2);
|
|
614449
614752
|
recoveredFiles.push(filePath);
|
|
614450
614753
|
recoveredTokens += referenceTokens;
|
|
614451
614754
|
continue;
|
|
@@ -614464,7 +614767,7 @@ ${branchNode.output}
|
|
|
614464
614767
|
const referenceTokens = Math.ceil(reference.length / 4);
|
|
614465
614768
|
if (recoveredTokens + referenceTokens <= fileRecoveryBudget) {
|
|
614466
614769
|
result.push({ role: "system", content: reference });
|
|
614467
|
-
alreadyVisiblePaths.add(
|
|
614770
|
+
alreadyVisiblePaths.add(canonicalPath2);
|
|
614468
614771
|
recoveredFiles.push(filePath);
|
|
614469
614772
|
recoveredTokens += referenceTokens;
|
|
614470
614773
|
}
|
|
@@ -614828,6 +615131,7 @@ ${trimmedNew}`;
|
|
|
614828
615131
|
...coverage?.gaps.slice(0, 3) ?? []
|
|
614829
615132
|
].filter(Boolean).join(" | ") || "none"}`,
|
|
614830
615133
|
`surviving_blockers=${[...blockedTodos, ...coverage?.gaps.slice(0, 3) ?? []].join(" | ") || "none"}`,
|
|
615134
|
+
`next_claim_inspection=${coverage?.nextInspection?.replace(/\s+/g, " ").slice(0, 420) || "none"}`,
|
|
614831
615135
|
`evidence_handles=${evidenceHandles.join(",") || "none"}`
|
|
614832
615136
|
];
|
|
614833
615137
|
const tier = this.options.modelTier ?? "large";
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.571",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "omnius",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.571",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED
|
@@ -50,7 +50,13 @@ correctness, transport routing, CAN fragmentation, or actuator behavior.
|
|
|
50
50
|
## Product and provenance coverage
|
|
51
51
|
|
|
52
52
|
If `.omnius/delivery-coverage.json` is present, it is the structured claim
|
|
53
|
-
contract. Read its gaps and keep final wording within the declared state.
|
|
53
|
+
contract. Read its gaps and keep final wording within the declared state. For
|
|
54
|
+
schema version 2, each non-blocked claim must name fresh, full, content-hashed
|
|
55
|
+
source inspections for every relevant boundary and at least one named
|
|
56
|
+
contradiction check grounded in those inspections. A grep result, directory
|
|
57
|
+
listing, partial read, stale read, or a summary of source does not satisfy an
|
|
58
|
+
inspection. Treat the first missing inspection as the next discovery action;
|
|
59
|
+
this is a state delta, not a standing recovery instruction.
|
|
54
60
|
Every product series, command, parameter, and model format claimed as
|
|
55
61
|
supported must map to exactly one source-backed contract and provenance record.
|
|
56
62
|
Each selected acceptance layer must also name its canonical verification
|