@c4a/context-cli 0.5.41-beta.4 → 0.5.41-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli.js +189 -133
- package/package.json +1 -1
- package/plugin/README.md +13 -11
- package/plugin/README_CN.md +13 -11
- package/plugin/commands/compile.md +1 -1
package/cli.js
CHANGED
|
@@ -38084,6 +38084,7 @@ var init_alignWorkflowStructureSchemas = __esm(() => {
|
|
|
38084
38084
|
"Skipping a relation-only, navigation-only, or placeholder-only source does not dispose of its coverable blocks. If you do not emit any Node for that source, still add an ownership_groups[] source_id rule that marks the source context_only or ignored; placeholder-only sources with no kept Node usually use ignored.",
|
|
38085
38085
|
"Emit depends_on only when cited blocks explicitly say one Node consumes, requires, calls, is configured by, or is downstream of another Node as a prerequisite, capability provider, upstream input, runtime dependency, or data-flow source. Direction is consumer/downstream -> provider/upstream.",
|
|
38086
38086
|
"Do not emit depends_on for parent/child containment, Related/See also lists, sibling co-occurrence, shared table membership, name similarity, or a plain mention without a dependency predicate.",
|
|
38087
|
+
"Use edges[].from/to for endpoints, or from_ref/to_ref for llm_slug_hint values. Do not use source/target or consumer/provider.",
|
|
38087
38088
|
"edges[].evidence_blocks must include the block that states the dependency. If the relation matters but evidence is missing, leave the edge out or add an unresolved question instead of guessing.",
|
|
38088
38089
|
"The persisted workspace truth remains canonical align-structure-decision; this schema is an authoring input only."
|
|
38089
38090
|
]
|
|
@@ -45537,7 +45538,7 @@ function nodeLanguageIssues(input) {
|
|
|
45537
45538
|
return [{
|
|
45538
45539
|
severity: "warning",
|
|
45539
45540
|
code: NODE_GENERATION_LANGUAGE_INCONSISTENT,
|
|
45540
|
-
message: `node ${fields.join("/")} appears to be English prose, but workspace generation language is Chinese`,
|
|
45541
|
+
message: `generated node metadata ${fields.join("/")} appears to be English prose, but workspace generation language is Chinese`,
|
|
45541
45542
|
path: input.path,
|
|
45542
45543
|
slug: input.node.id
|
|
45543
45544
|
}];
|
|
@@ -46954,13 +46955,15 @@ function staleSourceSnapshot(input) {
|
|
|
46954
46955
|
};
|
|
46955
46956
|
}
|
|
46956
46957
|
function pushStaleSourceSnapshotIssue(input) {
|
|
46958
|
+
const sourceRef = input.sourceRef ?? input.section.source_ref;
|
|
46957
46959
|
input.issues.push({
|
|
46958
46960
|
severity: "error",
|
|
46959
46961
|
code: "stale-node-source-snapshot",
|
|
46960
|
-
message: `section source_ref "${
|
|
46962
|
+
message: `section source_ref "${sourceRef}" cannot resolve because node.sources[] points to stale snapshot "${input.sourceEntry}" (latest @${input.stale.latest_snapshot_hash})`,
|
|
46961
46963
|
path: input.node.relativePath,
|
|
46962
46964
|
slug: input.node.parsed.node.id,
|
|
46963
|
-
sectionId: input.section.id
|
|
46965
|
+
sectionId: input.section.id,
|
|
46966
|
+
source_ref: sourceRef
|
|
46964
46967
|
});
|
|
46965
46968
|
}
|
|
46966
46969
|
function normalizedRawForCompare(value) {
|
|
@@ -47000,12 +47003,122 @@ function pushSectionRawStateIssues(input) {
|
|
|
47000
47003
|
});
|
|
47001
47004
|
}
|
|
47002
47005
|
}
|
|
47006
|
+
function pushRawSourceRefIssue(input) {
|
|
47007
|
+
input.issues.push({
|
|
47008
|
+
severity: "error",
|
|
47009
|
+
code: input.code,
|
|
47010
|
+
message: input.message,
|
|
47011
|
+
path: input.node.relativePath,
|
|
47012
|
+
slug: input.node.parsed.node.id,
|
|
47013
|
+
sectionId: input.section.id,
|
|
47014
|
+
source_ref: input.sourceRef
|
|
47015
|
+
});
|
|
47016
|
+
}
|
|
47017
|
+
async function validateRawSectionSourceRef(input) {
|
|
47018
|
+
const { ctxDir, node: node3, section, sourceRef, sourcesById, rawBlockCache, issues } = input;
|
|
47019
|
+
const parsed = parseSourceRef(sourceRef);
|
|
47020
|
+
if (!parsed) {
|
|
47021
|
+
pushRawSourceRefIssue({
|
|
47022
|
+
issues,
|
|
47023
|
+
node: node3,
|
|
47024
|
+
section,
|
|
47025
|
+
sourceRef,
|
|
47026
|
+
code: "invalid-source-ref",
|
|
47027
|
+
message: `section source_ref "${sourceRef}" must use ${SOURCE_REF_FORMAT_HINT}, for example ${SOURCE_REF_FORMAT_EXAMPLE}`
|
|
47028
|
+
});
|
|
47029
|
+
return null;
|
|
47030
|
+
}
|
|
47031
|
+
const aliasMatch = /^src-(\d+)#/.exec(sourceRef);
|
|
47032
|
+
const aliasIndex2 = Number(aliasMatch?.[1] ?? "0");
|
|
47033
|
+
if (aliasIndex2 <= 0 || aliasIndex2 > node3.parsed.node.sources.length) {
|
|
47034
|
+
pushRawSourceRefIssue({
|
|
47035
|
+
issues,
|
|
47036
|
+
node: node3,
|
|
47037
|
+
section,
|
|
47038
|
+
sourceRef,
|
|
47039
|
+
code: "dangling-source-alias",
|
|
47040
|
+
message: `section source_ref "${sourceRef}" points past node.sources[]`
|
|
47041
|
+
});
|
|
47042
|
+
return null;
|
|
47043
|
+
}
|
|
47044
|
+
const sourceEntry = node3.parsed.node.sources[aliasIndex2 - 1];
|
|
47045
|
+
if (!sourceEntry) {
|
|
47046
|
+
pushRawSourceRefIssue({
|
|
47047
|
+
issues,
|
|
47048
|
+
node: node3,
|
|
47049
|
+
section,
|
|
47050
|
+
sourceRef,
|
|
47051
|
+
code: "dangling-source-alias",
|
|
47052
|
+
message: `section source_ref "${sourceRef}" points to an empty node.sources[] slot`
|
|
47053
|
+
});
|
|
47054
|
+
return null;
|
|
47055
|
+
}
|
|
47056
|
+
const sourceId = sourceIdWithoutVersion(sourceEntry);
|
|
47057
|
+
const source2 = sourcesById.get(sourceId);
|
|
47058
|
+
if (source2?.status !== "active")
|
|
47059
|
+
return null;
|
|
47060
|
+
const stale = staleSourceSnapshot({ sourceEntry, source: source2 });
|
|
47061
|
+
if (stale !== null) {
|
|
47062
|
+
pushStaleSourceSnapshotIssue({ issues, node: node3, section, sourceEntry, sourceRef, stale });
|
|
47063
|
+
return null;
|
|
47064
|
+
}
|
|
47065
|
+
const resolvedSourceRef = await resolveHashedSourceRef({
|
|
47066
|
+
ctxDir,
|
|
47067
|
+
sourceRef,
|
|
47068
|
+
nodeSources: node3.parsed.node.sources,
|
|
47069
|
+
allowStableLocatorReanchor: true
|
|
47070
|
+
});
|
|
47071
|
+
if (resolvedSourceRef === null) {
|
|
47072
|
+
pushRawSourceRefIssue({
|
|
47073
|
+
issues,
|
|
47074
|
+
node: node3,
|
|
47075
|
+
section,
|
|
47076
|
+
sourceRef,
|
|
47077
|
+
code: "invalid-source-ref",
|
|
47078
|
+
message: `section source_ref "${sourceRef}" must include a valid @hash for a raw evidence block`
|
|
47079
|
+
});
|
|
47080
|
+
return null;
|
|
47081
|
+
}
|
|
47082
|
+
if (input.validateCanonical !== false && resolvedSourceRef.source_ref !== sourceRef) {
|
|
47083
|
+
pushRawSourceRefIssue({
|
|
47084
|
+
issues,
|
|
47085
|
+
node: node3,
|
|
47086
|
+
section,
|
|
47087
|
+
sourceRef,
|
|
47088
|
+
code: "invalid-source-ref",
|
|
47089
|
+
message: `section source_ref "${sourceRef}" is not canonical; expected "${resolvedSourceRef.source_ref}"`
|
|
47090
|
+
});
|
|
47091
|
+
return null;
|
|
47092
|
+
}
|
|
47093
|
+
if (input.validateRawOverlap !== false) {
|
|
47094
|
+
const hasOverlap = await sourceRefHasRawBlockOverlap({
|
|
47095
|
+
ctxDir,
|
|
47096
|
+
source: source2,
|
|
47097
|
+
cache: rawBlockCache,
|
|
47098
|
+
lineStart: parsed.lineStart,
|
|
47099
|
+
lineEnd: parsed.lineEnd,
|
|
47100
|
+
sourceEntry
|
|
47101
|
+
});
|
|
47102
|
+
if (hasOverlap === false) {
|
|
47103
|
+
pushRawSourceRefIssue({
|
|
47104
|
+
issues,
|
|
47105
|
+
node: node3,
|
|
47106
|
+
section,
|
|
47107
|
+
sourceRef,
|
|
47108
|
+
code: "source-ref-out-of-range",
|
|
47109
|
+
message: `section source_ref "${sourceRef}" does not overlap any raw block in latest source snapshot`
|
|
47110
|
+
});
|
|
47111
|
+
return null;
|
|
47112
|
+
}
|
|
47113
|
+
}
|
|
47114
|
+
return resolvedSourceRef;
|
|
47115
|
+
}
|
|
47003
47116
|
async function pushSectionReferenceIssues(input) {
|
|
47004
47117
|
const { node: node3, section, issues } = input;
|
|
47005
47118
|
if (section.status === SectionStatus.deprecated)
|
|
47006
47119
|
return;
|
|
47007
47120
|
pushSectionRawStateIssues({ issues, node: node3, section });
|
|
47008
|
-
const nodeHasCodeSource = node3.parsed.node.sources.some((
|
|
47121
|
+
const nodeHasCodeSource = node3.parsed.node.sources.some((source2) => sourceIdWithoutVersion(source2).startsWith("aspect:code:"));
|
|
47009
47122
|
for (const target of section.refers_to_nodes ?? []) {
|
|
47010
47123
|
if (!input.knownRefSlugs.has(target)) {
|
|
47011
47124
|
issues.push({
|
|
@@ -47027,6 +47140,21 @@ async function pushSectionReferenceIssues(input) {
|
|
|
47027
47140
|
});
|
|
47028
47141
|
}
|
|
47029
47142
|
}
|
|
47143
|
+
for (const sourceRef of [...new Set(section.source_refs ?? [])]) {
|
|
47144
|
+
if (sourceRef === section.source_ref)
|
|
47145
|
+
continue;
|
|
47146
|
+
await validateRawSectionSourceRef({
|
|
47147
|
+
ctxDir: input.ctxDir,
|
|
47148
|
+
node: node3,
|
|
47149
|
+
section,
|
|
47150
|
+
sourceRef,
|
|
47151
|
+
sourcesById: input.sourcesById,
|
|
47152
|
+
rawBlockCache: input.rawBlockCache,
|
|
47153
|
+
issues,
|
|
47154
|
+
validateRawOverlap: false,
|
|
47155
|
+
validateCanonical: false
|
|
47156
|
+
});
|
|
47157
|
+
}
|
|
47030
47158
|
if (section.source_ref.length === 0)
|
|
47031
47159
|
return;
|
|
47032
47160
|
const dispatch = dispatchSourceRef(node3.parsed.node.sources, section.source_ref);
|
|
@@ -47065,13 +47193,13 @@ async function pushSectionReferenceIssues(input) {
|
|
|
47065
47193
|
});
|
|
47066
47194
|
return;
|
|
47067
47195
|
}
|
|
47068
|
-
const
|
|
47196
|
+
const source2 = input.sourcesById.get(sourceIdWithoutVersion(dispatch.sourceEntry));
|
|
47069
47197
|
await pushCodeSourceReferenceIssues({
|
|
47070
47198
|
ctxDir: input.ctxDir,
|
|
47071
47199
|
node: node3,
|
|
47072
47200
|
section,
|
|
47073
47201
|
sourceEntry: dispatch.sourceEntry,
|
|
47074
|
-
source:
|
|
47202
|
+
source: source2,
|
|
47075
47203
|
parsed: dispatch.code,
|
|
47076
47204
|
issues
|
|
47077
47205
|
});
|
|
@@ -47089,11 +47217,11 @@ async function pushSectionReferenceIssues(input) {
|
|
|
47089
47217
|
});
|
|
47090
47218
|
return;
|
|
47091
47219
|
}
|
|
47092
|
-
const
|
|
47093
|
-
if (
|
|
47094
|
-
const
|
|
47095
|
-
if (
|
|
47096
|
-
pushStaleSourceSnapshotIssue({ issues, node: node3, section, sourceEntry: dispatch.sourceEntry, stale
|
|
47220
|
+
const source2 = input.sourcesById.get(sourceIdWithoutVersion(dispatch.sourceEntry));
|
|
47221
|
+
if (source2 !== undefined) {
|
|
47222
|
+
const stale = staleSourceSnapshot({ sourceEntry: dispatch.sourceEntry, source: source2 });
|
|
47223
|
+
if (stale !== null) {
|
|
47224
|
+
pushStaleSourceSnapshotIssue({ issues, node: node3, section, sourceEntry: dispatch.sourceEntry, stale });
|
|
47097
47225
|
return;
|
|
47098
47226
|
}
|
|
47099
47227
|
}
|
|
@@ -47102,103 +47230,22 @@ async function pushSectionReferenceIssues(input) {
|
|
|
47102
47230
|
node: node3,
|
|
47103
47231
|
section,
|
|
47104
47232
|
sourceEntry: dispatch.sourceEntry,
|
|
47105
|
-
source:
|
|
47233
|
+
source: source2,
|
|
47106
47234
|
parsed: dispatch.aspectFile,
|
|
47107
47235
|
issues
|
|
47108
47236
|
});
|
|
47109
47237
|
return;
|
|
47110
47238
|
}
|
|
47111
|
-
const
|
|
47112
|
-
if (!parsed) {
|
|
47113
|
-
issues.push({
|
|
47114
|
-
severity: "error",
|
|
47115
|
-
code: "invalid-source-ref",
|
|
47116
|
-
message: `section source_ref "${section.source_ref}" must use ${SOURCE_REF_FORMAT_HINT}, for example ${SOURCE_REF_FORMAT_EXAMPLE}`,
|
|
47117
|
-
path: node3.relativePath,
|
|
47118
|
-
slug: node3.parsed.node.id,
|
|
47119
|
-
sectionId: section.id
|
|
47120
|
-
});
|
|
47121
|
-
return;
|
|
47122
|
-
}
|
|
47123
|
-
const aliasMatch = /^src-(\d+)#/.exec(section.source_ref);
|
|
47124
|
-
const aliasIndex2 = Number(aliasMatch?.[1] ?? "0");
|
|
47125
|
-
if (aliasIndex2 <= 0 || aliasIndex2 > node3.parsed.node.sources.length) {
|
|
47126
|
-
issues.push({
|
|
47127
|
-
severity: "error",
|
|
47128
|
-
code: "dangling-source-alias",
|
|
47129
|
-
message: `section source_ref "${section.source_ref}" points past node.sources[]`,
|
|
47130
|
-
path: node3.relativePath,
|
|
47131
|
-
slug: node3.parsed.node.id,
|
|
47132
|
-
sectionId: section.id
|
|
47133
|
-
});
|
|
47134
|
-
return;
|
|
47135
|
-
}
|
|
47136
|
-
const sourceEntry = node3.parsed.node.sources[aliasIndex2 - 1];
|
|
47137
|
-
if (!sourceEntry) {
|
|
47138
|
-
issues.push({
|
|
47139
|
-
severity: "error",
|
|
47140
|
-
code: "dangling-source-alias",
|
|
47141
|
-
message: `section source_ref "${section.source_ref}" points to an empty node.sources[] slot`,
|
|
47142
|
-
path: node3.relativePath,
|
|
47143
|
-
slug: node3.parsed.node.id,
|
|
47144
|
-
sectionId: section.id
|
|
47145
|
-
});
|
|
47146
|
-
return;
|
|
47147
|
-
}
|
|
47148
|
-
const sourceId = sourceIdWithoutVersion(sourceEntry);
|
|
47149
|
-
const source2 = input.sourcesById.get(sourceId);
|
|
47150
|
-
if (source2?.status !== "active")
|
|
47151
|
-
return;
|
|
47152
|
-
const stale = staleSourceSnapshot({ sourceEntry, source: source2 });
|
|
47153
|
-
if (stale !== null) {
|
|
47154
|
-
pushStaleSourceSnapshotIssue({ issues, node: node3, section, sourceEntry, stale });
|
|
47155
|
-
return;
|
|
47156
|
-
}
|
|
47157
|
-
const resolvedSourceRef = await resolveHashedSourceRef({
|
|
47239
|
+
const resolvedSourceRef = await validateRawSectionSourceRef({
|
|
47158
47240
|
ctxDir: input.ctxDir,
|
|
47241
|
+
node: node3,
|
|
47242
|
+
section,
|
|
47159
47243
|
sourceRef: section.source_ref,
|
|
47160
|
-
|
|
47161
|
-
|
|
47244
|
+
sourcesById: input.sourcesById,
|
|
47245
|
+
rawBlockCache: input.rawBlockCache,
|
|
47246
|
+
issues
|
|
47162
47247
|
});
|
|
47163
47248
|
if (resolvedSourceRef === null) {
|
|
47164
|
-
issues.push({
|
|
47165
|
-
severity: "error",
|
|
47166
|
-
code: "invalid-source-ref",
|
|
47167
|
-
message: `section source_ref "${section.source_ref}" must include a valid @hash for a raw evidence block`,
|
|
47168
|
-
path: node3.relativePath,
|
|
47169
|
-
slug: node3.parsed.node.id,
|
|
47170
|
-
sectionId: section.id
|
|
47171
|
-
});
|
|
47172
|
-
return;
|
|
47173
|
-
}
|
|
47174
|
-
if (resolvedSourceRef.source_ref !== section.source_ref) {
|
|
47175
|
-
issues.push({
|
|
47176
|
-
severity: "error",
|
|
47177
|
-
code: "invalid-source-ref",
|
|
47178
|
-
message: `section source_ref "${section.source_ref}" is not canonical; expected "${resolvedSourceRef.source_ref}"`,
|
|
47179
|
-
path: node3.relativePath,
|
|
47180
|
-
slug: node3.parsed.node.id,
|
|
47181
|
-
sectionId: section.id
|
|
47182
|
-
});
|
|
47183
|
-
return;
|
|
47184
|
-
}
|
|
47185
|
-
const hasOverlap = await sourceRefHasRawBlockOverlap({
|
|
47186
|
-
ctxDir: input.ctxDir,
|
|
47187
|
-
source: source2,
|
|
47188
|
-
cache: input.rawBlockCache,
|
|
47189
|
-
lineStart: parsed.lineStart,
|
|
47190
|
-
lineEnd: parsed.lineEnd,
|
|
47191
|
-
sourceEntry
|
|
47192
|
-
});
|
|
47193
|
-
if (hasOverlap === false) {
|
|
47194
|
-
issues.push({
|
|
47195
|
-
severity: "error",
|
|
47196
|
-
code: "source-ref-out-of-range",
|
|
47197
|
-
message: `section source_ref "${section.source_ref}" does not overlap any raw block in latest source snapshot`,
|
|
47198
|
-
path: node3.relativePath,
|
|
47199
|
-
slug: node3.parsed.node.id,
|
|
47200
|
-
sectionId: section.id
|
|
47201
|
-
});
|
|
47202
47249
|
return;
|
|
47203
47250
|
}
|
|
47204
47251
|
const sectionEvidence = sectionEvidenceText(section);
|
|
@@ -61258,8 +61305,8 @@ var init_agentHintRegistry = __esm(() => {
|
|
|
61258
61305
|
{
|
|
61259
61306
|
code: "align-node-generation-language-inconsistent",
|
|
61260
61307
|
severity: "warning",
|
|
61261
|
-
description: "
|
|
61262
|
-
trigger: "Align validate/finalize sees English-looking node.title or node.summary while align-segments.generation_policy.language is Chinese.",
|
|
61308
|
+
description: "Generated Node metadata appears to use a different language from the workspace generation policy.",
|
|
61309
|
+
trigger: "Align validate/finalize sees English-looking node.title or node.summary while align-segments.generation_policy.language is Chinese. Source-bound Section content can still follow the cited source language.",
|
|
61263
61310
|
command: "context schema align-structure-intent --view minimal --format json"
|
|
61264
61311
|
},
|
|
61265
61312
|
{
|
|
@@ -62139,17 +62186,17 @@ function compileAgentEngagementSummary(input) {
|
|
|
62139
62186
|
const writeRecords = input.records.filter((record) => record.mode === "compile" && record.action !== "duplicate_skip" && record.action !== "omit" && record.action !== "ask_user");
|
|
62140
62187
|
const citedRefs = new Set(writeRecords.flatMap(refsFromRecord));
|
|
62141
62188
|
const templateLikeActions = writeRecords.filter((record) => contentFromRecord(record).some(isTemplateLikeContent)).length;
|
|
62142
|
-
const derivedPrimaryTotal = citedRefs.size + input.coverage.breakdown.primary_unresolved_total + input.coverage.breakdown.
|
|
62189
|
+
const derivedPrimaryTotal = citedRefs.size + input.coverage.breakdown.primary_unresolved_total + input.coverage.breakdown.primary_skipped_total;
|
|
62143
62190
|
const primaryTotal = Math.max(input.coverage.breakdown.primary_content_refs_total, derivedPrimaryTotal);
|
|
62144
62191
|
const unsupportedOrLowSupport = writeRecords.filter((record) => record.action === "remove_unsupported" || judgeSupportVerdict(record) === "weak" || judgeSupportVerdict(record) === "unsupported").length + input.coverage.breakdown.blocking_unresolved;
|
|
62145
|
-
const severity = writeRecords.length > 0 && citedRefs.size === 0 || primaryTotal > LOW_CITATION_PRIMARY_TOTAL_THRESHOLD && citedRefs.size / primaryTotal < LOW_CITATION_RATE_THRESHOLD || writeRecords.length >= 3 && (input.evidenceViews?.expected_evidence_views_total ?? 0) >= 3 && (input.evidenceViews?.expected_evidence_views_read ?? 0) <= (input.evidenceViews?.expected_evidence_views_total ?? 0) / 3 || templateLikeActions > 0 || unsupportedOrLowSupport > 0 ? "warning" : "info";
|
|
62192
|
+
const severity = writeRecords.length > 0 && citedRefs.size === 0 || writeRecords.length > 0 && primaryTotal > LOW_CITATION_PRIMARY_TOTAL_THRESHOLD && citedRefs.size / primaryTotal < LOW_CITATION_RATE_THRESHOLD || writeRecords.length >= 3 && (input.evidenceViews?.expected_evidence_views_total ?? 0) >= 3 && (input.evidenceViews?.expected_evidence_views_read ?? 0) <= (input.evidenceViews?.expected_evidence_views_total ?? 0) / 3 || templateLikeActions > 0 || unsupportedOrLowSupport > 0 ? "warning" : "info";
|
|
62146
62193
|
return {
|
|
62147
62194
|
written_actions: writeRecords.length,
|
|
62148
62195
|
primary_citable_refs_total: primaryTotal,
|
|
62149
62196
|
cited_refs_count: citedRefs.size,
|
|
62150
62197
|
...input.evidenceViews?.expected_evidence_views_total !== undefined ? { expected_evidence_views_total: input.evidenceViews.expected_evidence_views_total } : {},
|
|
62151
62198
|
...input.evidenceViews?.expected_evidence_views_read !== undefined ? { expected_evidence_views_read: input.evidenceViews.expected_evidence_views_read } : {},
|
|
62152
|
-
unexpanded_primary_refs: Math.max(0, primaryTotal - citedRefs.size),
|
|
62199
|
+
unexpanded_primary_refs: writeRecords.length === 0 ? 0 : Math.max(0, primaryTotal - citedRefs.size),
|
|
62153
62200
|
full_text_requests: input.evidenceViews?.full_text_requests ?? 0,
|
|
62154
62201
|
template_like_actions: templateLikeActions,
|
|
62155
62202
|
unsupported_or_low_support_actions: unsupportedOrLowSupport,
|
|
@@ -81588,6 +81635,7 @@ async function preflightSemanticDecisions(input) {
|
|
|
81588
81635
|
const current = findTargetSection(node3, target.section_id, decision.action);
|
|
81589
81636
|
const reanchorPatch = {
|
|
81590
81637
|
...decision.proposed?.source_ref !== undefined ? { source_ref: decision.proposed.source_ref } : {},
|
|
81638
|
+
...decision.proposed?.source_refs !== undefined ? { source_refs: decision.proposed.source_refs } : {},
|
|
81591
81639
|
...decision.proposed?.confidence !== undefined ? { confidence: decision.proposed.confidence } : {}
|
|
81592
81640
|
};
|
|
81593
81641
|
const finalSection = finalSectionFromPatch(current, reanchorPatch);
|
|
@@ -81619,7 +81667,8 @@ async function preflightSemanticDecisions(input) {
|
|
|
81619
81667
|
ctxDir: input.ctxDir,
|
|
81620
81668
|
nodeSources: node3.parsed.node.sources,
|
|
81621
81669
|
section,
|
|
81622
|
-
action: decision.action
|
|
81670
|
+
action: decision.action,
|
|
81671
|
+
sourceRefs: proposed.source_refs
|
|
81623
81672
|
});
|
|
81624
81673
|
}
|
|
81625
81674
|
}
|
|
@@ -82452,14 +82501,21 @@ async function canonicalizeProposedForNode(input) {
|
|
|
82452
82501
|
const [sourceRef, sourceRefs2, sections] = await Promise.all([
|
|
82453
82502
|
typeof input.proposed.source_ref === "string" ? canonicalizeSourceRefForNode({ ctxDir: input.ctxDir, node: input.node, sourceRef: input.proposed.source_ref }) : Promise.resolve(undefined),
|
|
82454
82503
|
input.proposed.source_refs !== undefined ? Promise.all(input.proposed.source_refs.map((ref) => canonicalizeSourceRefForNode({ ctxDir: input.ctxDir, node: input.node, sourceRef: ref }))) : Promise.resolve(undefined),
|
|
82455
|
-
input.proposed.sections !== undefined ? Promise.all(input.proposed.sections.map(async (section) =>
|
|
82456
|
-
|
|
82457
|
-
|
|
82458
|
-
|
|
82459
|
-
|
|
82460
|
-
|
|
82461
|
-
|
|
82462
|
-
|
|
82504
|
+
input.proposed.sections !== undefined ? Promise.all(input.proposed.sections.map(async (section) => {
|
|
82505
|
+
const [sectionSourceRef, sectionSourceRefs2] = await Promise.all([
|
|
82506
|
+
canonicalizeSourceRefForNode({
|
|
82507
|
+
ctxDir: input.ctxDir,
|
|
82508
|
+
node: input.node,
|
|
82509
|
+
sourceRef: section.source_ref
|
|
82510
|
+
}),
|
|
82511
|
+
section.source_refs !== undefined ? Promise.all(section.source_refs.map((ref) => canonicalizeSourceRefForNode({ ctxDir: input.ctxDir, node: input.node, sourceRef: ref }))) : Promise.resolve(undefined)
|
|
82512
|
+
]);
|
|
82513
|
+
return {
|
|
82514
|
+
...section,
|
|
82515
|
+
source_ref: sectionSourceRef,
|
|
82516
|
+
...sectionSourceRefs2 !== undefined ? { source_refs: [...new Set(sectionSourceRefs2)] } : {}
|
|
82517
|
+
};
|
|
82518
|
+
})) : Promise.resolve(undefined)
|
|
82463
82519
|
]);
|
|
82464
82520
|
return {
|
|
82465
82521
|
...input.proposed,
|
|
@@ -82593,6 +82649,7 @@ async function applyReanchorPrimitive(input) {
|
|
|
82593
82649
|
sectionId: input.sectionId,
|
|
82594
82650
|
patch: {
|
|
82595
82651
|
source_ref: input.proposed.source_ref,
|
|
82652
|
+
...input.proposed.source_refs !== undefined ? { source_refs: input.proposed.source_refs } : {},
|
|
82596
82653
|
confidence: input.proposed.confidence
|
|
82597
82654
|
}
|
|
82598
82655
|
});
|
|
@@ -88983,7 +89040,7 @@ function projectNodeContextSourceRefsIndex(value, options = {}, baseCommand = "c
|
|
|
88983
89040
|
selectionPolicy: {
|
|
88984
89041
|
...SOURCE_REFS_SELECTION_POLICY,
|
|
88985
89042
|
id: "source-refs-index-v1",
|
|
88986
|
-
note: "Compact block id index for compile-draft source_block_ids shorthand."
|
|
89043
|
+
note: "Compact block id index for compile-draft source_block_ids shorthand; multi-block actions must stay within one same-source contiguous citation-eligible run."
|
|
88987
89044
|
},
|
|
88988
89045
|
howToExplore: sourceRefsHowToExplore({
|
|
88989
89046
|
rows,
|
|
@@ -89001,7 +89058,7 @@ function projectNodeContextSourceRefsIndex(value, options = {}, baseCommand = "c
|
|
|
89001
89058
|
view_of: "NodeContext.raw_snippets",
|
|
89002
89059
|
projection_mode: projectionMode,
|
|
89003
89060
|
current_workset_scope: projectionScope,
|
|
89004
|
-
usage: "Use items[].block_id in compile-draft actions[].source_block_ids. Open source-refs detail only when text preview or canonical source_ref strings are needed.",
|
|
89061
|
+
usage: "Use items[].block_id in compile-draft actions[].source_block_ids. For multi-block actions, use one same-source contiguous citation-eligible run; split around skipped citation-eligible rows or run draft-scaffold when unsure. Open source-refs detail only when text preview or canonical source_ref strings are needed.",
|
|
89005
89062
|
...isRecord37(value.incremental) ? { incremental: stripAgentInternalPathFields(value.incremental) } : {},
|
|
89006
89063
|
...Object.keys(filters).length > 0 ? { filters } : {},
|
|
89007
89064
|
...window2,
|
|
@@ -91698,9 +91755,10 @@ function normalizeEdges(value, refs, slugs) {
|
|
|
91698
91755
|
if (raw.edge_type !== "depends_on" && raw.type !== "depends_on") {
|
|
91699
91756
|
rejectLegacy(`edges[${index2}].edge_type`, `document edge type must be depends_on; allowed runtime EdgeType values are ${EDGE_TYPES.join("|")}`);
|
|
91700
91757
|
}
|
|
91701
|
-
const unsupportedEndpointFields = ["consumer", "provider"].filter((field) => Object.prototype.hasOwnProperty.call(raw, field));
|
|
91758
|
+
const unsupportedEndpointFields = ["consumer", "provider", "source", "target"].filter((field) => Object.prototype.hasOwnProperty.call(raw, field));
|
|
91702
91759
|
if (unsupportedEndpointFields.length > 0) {
|
|
91703
|
-
|
|
91760
|
+
const endpointLabel = unsupportedEndpointFields.join("/");
|
|
91761
|
+
reject(`edges[${index2}]`, `edge endpoint fields ${endpointLabel} are not supported; use from/to or from_ref/to_ref`, {
|
|
91704
91762
|
reasonCode: "edge-endpoint-fields-unsupported",
|
|
91705
91763
|
currentValue: Object.fromEntries(unsupportedEndpointFields.map((field) => [field, raw[field]])),
|
|
91706
91764
|
availableNodeRefs: nodeRefsForHint(refs),
|
|
@@ -91713,6 +91771,7 @@ function normalizeEdges(value, refs, slugs) {
|
|
|
91713
91771
|
}, null, 2),
|
|
91714
91772
|
repairOptions: [
|
|
91715
91773
|
"Rename consumer to from and provider to to.",
|
|
91774
|
+
"Rename source to from and target to to.",
|
|
91716
91775
|
"Use from_ref/to_ref when referring to llm_slug_hint values."
|
|
91717
91776
|
]
|
|
91718
91777
|
});
|
|
@@ -93386,7 +93445,7 @@ function agentHintsForNodeLanguageWarnings(input) {
|
|
|
93386
93445
|
message: issue2.message,
|
|
93387
93446
|
path: issue2.path,
|
|
93388
93447
|
target_node: issue2.slug,
|
|
93389
|
-
next_action: "Revise node.title or node.summary to follow align-segments.generation_policy.language, then rerun context align validate. Preserve product names, code identifiers, slugs, flags, block_id tokens, and citation tokens exactly when needed.",
|
|
93448
|
+
next_action: "Revise generated node.title or node.summary to follow align-segments.generation_policy.language, then rerun context align validate. This warning does not require translating source-bound Section content. Preserve product names, code identifiers, slugs, flags, block_id tokens, and citation tokens exactly when needed.",
|
|
93390
93449
|
command: "context schema align-structure-intent --view minimal --format json",
|
|
93391
93450
|
diagnostics: {
|
|
93392
93451
|
...input.expectedLanguage !== undefined ? { expected_language: input.expectedLanguage } : {},
|
|
@@ -97656,12 +97715,10 @@ function splitActionTemplate(original, split, index2) {
|
|
|
97656
97715
|
delete action.source_block_ids;
|
|
97657
97716
|
delete action.body;
|
|
97658
97717
|
delete action.raw;
|
|
97718
|
+
delete action.summary;
|
|
97719
|
+
delete action.detail;
|
|
97659
97720
|
action.source_refs = split.source_refs;
|
|
97660
97721
|
action.content = `<rewrite content for split ${index2 + 1}; cite only listed source_refs>`;
|
|
97661
|
-
if (typeof action.summary === "string")
|
|
97662
|
-
action.summary = `<optional summary for split ${index2 + 1}>`;
|
|
97663
|
-
if (typeof action.detail === "string")
|
|
97664
|
-
action.detail = `<optional detail for split ${index2 + 1}>`;
|
|
97665
97722
|
return action;
|
|
97666
97723
|
}
|
|
97667
97724
|
function suggestedSplitPatchTemplate(input) {
|
|
@@ -98693,14 +98750,12 @@ function draftActionTemplate(kind, rows) {
|
|
|
98693
98750
|
return {
|
|
98694
98751
|
op: "add",
|
|
98695
98752
|
kind,
|
|
98696
|
-
summary: "<write recall summary with object, mechanism, constraint, action, or entry term>",
|
|
98697
98753
|
source_block_ids: sourceBlockIds2
|
|
98698
98754
|
};
|
|
98699
98755
|
}
|
|
98700
98756
|
return {
|
|
98701
98757
|
op: "add",
|
|
98702
98758
|
kind,
|
|
98703
|
-
summary: "<write recall summary with object, mechanism, constraint, action, or entry term>",
|
|
98704
98759
|
source_refs: rows.map((row) => row.source_ref)
|
|
98705
98760
|
};
|
|
98706
98761
|
}
|
|
@@ -99478,7 +99533,7 @@ function plannedTemplateActions(sectionGroups) {
|
|
|
99478
99533
|
return plannedReadySectionGroups(sectionGroups).flatMap((group) => recordArray3(group.draft_action_templates));
|
|
99479
99534
|
}
|
|
99480
99535
|
function scaffoldUsage() {
|
|
99481
|
-
return "Confirm each action.kind
|
|
99536
|
+
return "Confirm each action.kind; add a recall-focused summary only when it improves reader or query output. Omit content by default because the CLI mirrors cited raw from source_block_ids/source_refs. Add content only for intentional translation, structural rewrite, or formatting preservation; c4a:raw is written only for rewritten evidence. Keep hard citation-gap actions separate; if one action cites multiple source_block_ids/source_refs, they must form one contiguous citation-eligible run from the same source, with no intervening citation-eligible block owned by another action. Read section_group_annotations when present because heading/local-heading annotations are context for your semantic split decision. Submit with context compile cycle <node> --input - --format json, or context compile draft <node> --input - for manual review.";
|
|
99482
99537
|
}
|
|
99483
99538
|
function stringArray10(value) {
|
|
99484
99539
|
return Array.isArray(value) ? value.filter((item) => typeof item === "string" && item.length > 0) : [];
|
|
@@ -99516,9 +99571,10 @@ function requestFullTextCommands(action, rows) {
|
|
|
99516
99571
|
function scaffoldAction(action, refersToNodeCandidates = []) {
|
|
99517
99572
|
const out2 = {
|
|
99518
99573
|
op: typeof action.op === "string" ? action.op : "add",
|
|
99519
|
-
kind: typeof action.kind === "string" ? action.kind : "description"
|
|
99520
|
-
summary: typeof action.summary === "string" && action.summary.length > 0 ? action.summary : "<write recall summary with object, mechanism, constraint, action, or entry term>"
|
|
99574
|
+
kind: typeof action.kind === "string" ? action.kind : "description"
|
|
99521
99575
|
};
|
|
99576
|
+
if (typeof action.summary === "string" && action.summary.length > 0)
|
|
99577
|
+
out2.summary = action.summary;
|
|
99522
99578
|
const sourceBlockIds2 = stringArray10(action.source_block_ids);
|
|
99523
99579
|
const sourceRefs2 = stringArray10(action.source_refs);
|
|
99524
99580
|
const refersToNodes = uniqueStrings6([
|
|
@@ -99610,7 +99666,6 @@ function sourceRefsDraftScaffold(input) {
|
|
|
99610
99666
|
const scaffold = scaffoldAction({
|
|
99611
99667
|
op: "add",
|
|
99612
99668
|
kind,
|
|
99613
|
-
summary: "<write recall summary with object, mechanism, constraint, action, or entry term>",
|
|
99614
99669
|
source_block_ids: typeof row.block_id === "string" ? [row.block_id] : []
|
|
99615
99670
|
}, input.refersToNodeCandidates);
|
|
99616
99671
|
const commands = requestFullTextCommands(scaffold, selectedRows);
|
|
@@ -99836,7 +99891,7 @@ function sourceRefsSectionGroupHint(sectionGroups) {
|
|
|
99836
99891
|
code: "compile-source-refs-planned-section-groups",
|
|
99837
99892
|
severity: "info",
|
|
99838
99893
|
message: "planned_section_groups is the primary source-refs authoring path for finalized align section plans.",
|
|
99839
|
-
next_action: splitCount > 0 ? "Use each hard-split planned_section_groups[].draft_action_templates entry as a separate draft action because non-contiguous evidence cannot form one source_ref. heading_spans/local_headings are annotations, not split commands." : "Use planned_section_groups[].draft_action_templates as the default align section scaffold. Confirm kind
|
|
99894
|
+
next_action: splitCount > 0 ? "Use each hard-split planned_section_groups[].draft_action_templates entry as a separate draft action because non-contiguous evidence cannot form one source_ref. heading_spans/local_headings are annotations, not split commands." : "Use planned_section_groups[].draft_action_templates as the default align section scaffold. Confirm kind; add summary only when it improves reader or query output. Keep source_block_ids shorthand when present; heading_spans/local_headings are annotations when present, not split commands.",
|
|
99840
99895
|
diagnostics: {
|
|
99841
99896
|
planned_section_groups: sectionGroups.length,
|
|
99842
99897
|
split_planned_section_groups: splitCount,
|
|
@@ -99861,7 +99916,7 @@ function sourceRefsDenseHintWithSectionGroups(hint, sectionGroups, visibleRows)
|
|
|
99861
99916
|
delete baseHint.next_action;
|
|
99862
99917
|
const plannedSuffix = sectionGroups.length > 0 ? " planned_section_groups are available for finalized align section plans." : "";
|
|
99863
99918
|
const countSuffix = fullCount !== undefined && fullCount > visibleCitationRows.length ? ` (${fullCount} total in the NodeContext).` : ".";
|
|
99864
|
-
const nextAction = sectionGroups.length > 0 ? "Use planned_section_groups[].draft_action_templates first as the align section scaffold. Confirm kind
|
|
99919
|
+
const nextAction = sectionGroups.length > 0 ? "Use planned_section_groups[].draft_action_templates first as the align section scaffold. Confirm kind; add summary only when it improves reader or query output. Fallback may split finer only when a planned group is missing, needs attention, or you intentionally need finer-grained Sections. Treat heading_spans/local_headings as context annotations, not required prefixes." : hint.next_action;
|
|
99865
99920
|
return {
|
|
99866
99921
|
...baseHint,
|
|
99867
99922
|
message: `${visibleCitationRows.length} citation-eligible snippet(s)${sourceId !== undefined ? ` from ${sourceId}` : ""} are visible in this source-refs view${countSuffix}${plannedSuffix}`,
|
|
@@ -100035,7 +100090,7 @@ function sourceRefsNextActionEnvelope(input) {
|
|
|
100035
100090
|
views: [
|
|
100036
100091
|
{
|
|
100037
100092
|
id: "source-refs-index",
|
|
100038
|
-
purpose: "Compact source-ref index contains block ids eligible for compile draft source_block_ids.",
|
|
100093
|
+
purpose: "Compact source-ref index contains block ids eligible for compile draft source_block_ids; multi-block actions must stay within one same-source contiguous citation-eligible run.",
|
|
100039
100094
|
evidence_role: "primary",
|
|
100040
100095
|
expected: true,
|
|
100041
100096
|
budget_safety: "compact",
|
|
@@ -100094,14 +100149,14 @@ function writeCompileSourceRefs(context, format, options = {}) {
|
|
|
100094
100149
|
code: "compile-source-refs-draft-scaffold-available",
|
|
100095
100150
|
severity: "info",
|
|
100096
100151
|
message: "source-refs view can emit a compile-draft skeleton so agents do not manually copy source_ref strings.",
|
|
100097
|
-
next_action: "Run the draft scaffold command
|
|
100152
|
+
next_action: "Run the draft scaffold command and confirm action.kind. Add action.summary only when it improves reader or query output; omit content by default because the CLI mirrors cited raw from source_block_ids. Add content only for intentional translation, structural rewrite, or formatting preservation. Keep hard citation-gap templates separate; split heading/local-heading annotated templates only when the cited evidence is semantically separable.",
|
|
100098
100153
|
command: draftScaffoldCommand
|
|
100099
100154
|
};
|
|
100100
100155
|
const indexHint = {
|
|
100101
100156
|
code: "compile-source-refs-index-ready",
|
|
100102
100157
|
severity: "info",
|
|
100103
100158
|
message: "source-refs-index is the compact Node-scoped citation index for source_block_ids; it intentionally omits quote previews.",
|
|
100104
|
-
next_action: "Use items[].block_id when the indexed row is the evidence you will cite. Open the detailed source-refs view only when you need quote preview or explicit source_refs.",
|
|
100159
|
+
next_action: "Use items[].block_id when the indexed row is the evidence you will cite. For multi-block actions, use block_ids from one same-source contiguous citation-eligible run; split around skipped citation-eligible rows, or run draft-scaffold when unsure. Open the detailed source-refs view only when you need quote preview or explicit source_refs.",
|
|
100105
100160
|
command: sourceRefsIndex,
|
|
100106
100161
|
detail_view_command: sourceRefsDetail
|
|
100107
100162
|
};
|
|
@@ -107125,6 +107180,7 @@ function alignStructureIntentFieldGuidance() {
|
|
|
107125
107180
|
},
|
|
107126
107181
|
edges: {
|
|
107127
107182
|
edge_type: "Only depends_on is accepted; direction is consumer/downstream -> provider/upstream.",
|
|
107183
|
+
endpoint_fields: "Use from/to for endpoints, or from_ref/to_ref for llm_slug_hint values. Do not use source/target or consumer/provider.",
|
|
107128
107184
|
evidence_blocks: "Include the block that explicitly states the dependency. Do not use edges for parent/child containment or Related/See also links."
|
|
107129
107185
|
}
|
|
107130
107186
|
};
|
package/package.json
CHANGED
package/plugin/README.md
CHANGED
|
@@ -107,17 +107,19 @@ The compiled knowledge base can be packaged for distribution:
|
|
|
107
107
|
|
|
108
108
|
The numbers below come from a parallel benchmark: each model runs the full c4a flow (capture → align → compile) end-to-end over the same 10-document business corpus, with no manual intervention. Quality is scored across 7 dimensions (totaling 100) based on the resulting knowledge base; duration covers the full flow from `context init` to `compile close`.
|
|
109
109
|
|
|
110
|
-
| Dimension |
|
|
111
|
-
|
|
112
|
-
| Fact coverage
|
|
113
|
-
| Fact fidelity
|
|
114
|
-
| Structure
|
|
115
|
-
| URL
|
|
116
|
-
|
|
|
117
|
-
| Section boundary
|
|
118
|
-
|
|
|
119
|
-
| **Total** | **
|
|
120
|
-
| Duration |
|
|
110
|
+
| Dimension | GPT 5.5 xh fast | GPT 5.5 m fast | Opus 4.8 | Sonnet 4.6 | DeepSeek V4 Pro | V4 Flash |
|
|
111
|
+
|---|---:|---:|---:|---:|---:|---:|
|
|
112
|
+
| Fact coverage | 24 | 24 | 24 | 23 | 24 | 23 |
|
|
113
|
+
| Fact fidelity | 25 | 25 | 25 | 25 | 25 | 25 |
|
|
114
|
+
| Structure | 15 | 15 | 15 | 14 | 15 | 14 |
|
|
115
|
+
| URL | 5 | 5 | 5 | 5 | 5 | 5 |
|
|
116
|
+
| Evidence link | 10 | 10 | 10 | 10 | 10 | 7 |
|
|
117
|
+
| Section boundary | 9 | 9 | 8 | 9 | 9 | 3 |
|
|
118
|
+
| Modeling | 9 | 9 | 8 | 8 | 7 | 6 |
|
|
119
|
+
| **Total** | **97** | **97** | **95** | **94** | **95** | **83** |
|
|
120
|
+
| Duration | 5m44s | 4m34s | 20m27s | 20m20s | ~9m28s | 2m37s |
|
|
121
|
+
|
|
122
|
+
> GPT 5.5 xh fast / GPT 5.5 m fast run on Codex; Opus 4.8 / Sonnet 4.6 / DeepSeek V4 Pro / V4 Flash run on Claude.
|
|
121
123
|
|
|
122
124
|
## About this repository
|
|
123
125
|
|
package/plugin/README_CN.md
CHANGED
|
@@ -105,17 +105,19 @@ bun add -g @c4a/context-cli
|
|
|
105
105
|
|
|
106
106
|
下方数据来自一次并发基准测试:每个模型在同一份 10 篇业务文档语料上端到端跑完 c4a 全流程(capture → align → compile),无人工介入。质量按 7 个维度评分(总分 100)反映产物知识库;耗时覆盖 `context init` 到 `compile close` 的全流程。
|
|
107
107
|
|
|
108
|
-
| 维度 |
|
|
109
|
-
|
|
110
|
-
|
|
|
111
|
-
|
|
|
112
|
-
|
|
|
113
|
-
| URL
|
|
114
|
-
|
|
|
115
|
-
| Section
|
|
116
|
-
|
|
|
117
|
-
| **总分** | **
|
|
118
|
-
| 总耗时 |
|
|
108
|
+
| 维度 | GPT 5.5 xh fast | GPT 5.5 m fast | Opus 4.8 | Sonnet 4.6 | DeepSeek V4 Pro | V4 Flash |
|
|
109
|
+
|---|---:|---:|---:|---:|---:|---:|
|
|
110
|
+
| 事实覆盖 | 24 | 24 | 24 | 23 | 24 | 23 |
|
|
111
|
+
| 事实忠实 | 25 | 25 | 25 | 25 | 25 | 25 |
|
|
112
|
+
| 结构语义 | 15 | 15 | 15 | 14 | 15 | 14 |
|
|
113
|
+
| URL | 5 | 5 | 5 | 5 | 5 | 5 |
|
|
114
|
+
| 证据链 | 10 | 10 | 10 | 10 | 10 | 7 |
|
|
115
|
+
| Section 边界 | 9 | 9 | 8 | 9 | 9 | 3 |
|
|
116
|
+
| 建模 | 9 | 9 | 8 | 8 | 7 | 6 |
|
|
117
|
+
| **总分** | **97** | **97** | **95** | **94** | **95** | **83** |
|
|
118
|
+
| 总耗时 | 5m44s | 4m34s | 20m27s | 20m20s | ~9m28s | 2m37s |
|
|
119
|
+
|
|
120
|
+
> GPT 5.5 xh fast / GPT 5.5 m fast 运行于 Codex;Opus 4.8 / Sonnet 4.6 / DeepSeek V4 Pro / V4 Flash 运行于 Claude。
|
|
119
121
|
|
|
120
122
|
## 关于本仓库
|
|
121
123
|
|
|
@@ -57,7 +57,7 @@ Carry the latest envelope forward between iterations. After a successful node cy
|
|
|
57
57
|
|
|
58
58
|
Run the evidence command returned by the envelope before writing. `views[].expected` identifies the default compact evidence entry, not a separate checklist to exhaust. For compile evidence, prefer the CLI-returned source-ref/scaffold views. They may expose:
|
|
59
59
|
|
|
60
|
-
- `source_refs_index_command` / `source_refs_command` — compact Node-scoped citation index for drafting; use `items[].block_id` in `source_block_ids[]` when the row is the evidence you will cite.
|
|
60
|
+
- `source_refs_index_command` / `source_refs_command` — compact Node-scoped citation index for drafting; use `items[].block_id` in `source_block_ids[]` when the row is the evidence you will cite. Multiple block ids in one action must be one same-source contiguous citation-eligible run; split around skipped citation-eligible rows or use `--draft-scaffold` when unsure.
|
|
61
61
|
- `source_refs_detail_command` — detailed source refs with quote previews; open only when the compact index is not enough.
|
|
62
62
|
- `request_full_text_command` / `--view text` — narrow text view for one block when quote preview is not enough; this is still Node-scoped, not a workspace evidence bundle.
|
|
63
63
|
- `citable_source_refs[]` — detailed-view refs eligible for draft citations; prefer `block_id` values in `source_block_ids[]`.
|