@davesheffer/hunch 1.31.0 → 1.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -6
- package/dist/cli/automaticReviewMemory.d.ts +13 -0
- package/dist/cli/dna.d.ts +2 -0
- package/dist/cli/index.d.ts +16 -0
- package/dist/cli/index.js +602 -43
- package/dist/cli/integrations.d.ts +2 -0
- package/dist/cli/integrations.js +5 -2
- package/dist/cli/invocation.d.ts +35 -0
- package/dist/cli/preflight.d.ts +1 -0
- package/dist/cli/reviewMemory.d.ts +4 -0
- package/dist/cli/reviewMemoryProvider.d.ts +14 -0
- package/dist/cli/serve.d.ts +2 -0
- package/dist/cli/taskReport.d.ts +6 -0
- package/dist/cli/taskReport.js +124 -0
- package/dist/cli/update.d.ts +14 -0
- package/dist/client/state.d.ts +248 -0
- package/dist/client/state.js +2 -0
- package/dist/constitution/adapters.d.ts +29 -0
- package/dist/constitution/behaviorAttestationBinding.d.ts +3 -0
- package/dist/constitution/behaviorEvaluator.d.ts +8 -0
- package/dist/constitution/behaviorProof.d.ts +9 -0
- package/dist/constitution/behaviorWorkspace.d.ts +25 -0
- package/dist/constitution/bootstrap.d.ts +30 -0
- package/dist/constitution/canonical.d.ts +15 -0
- package/dist/constitution/card.d.ts +58 -0
- package/dist/constitution/compiler.d.ts +52 -0
- package/dist/constitution/composition.d.ts +10 -0
- package/dist/constitution/corpus.d.ts +7 -0
- package/dist/constitution/correctionPolicyMaterializer.d.ts +57 -0
- package/dist/constitution/delta.d.ts +4 -0
- package/dist/constitution/disposition.d.ts +20 -0
- package/dist/constitution/evaluator.d.ts +47 -0
- package/dist/constitution/experiment.d.ts +466 -0
- package/dist/constitution/experimentRunner.d.ts +7 -0
- package/dist/constitution/g2.d.ts +209 -0
- package/dist/constitution/g2BehaviorAttestation.d.ts +45 -0
- package/dist/constitution/g2BehaviorCandidates.d.ts +123 -0
- package/dist/constitution/g2BehaviorDependencies.d.ts +83 -0
- package/dist/constitution/g2BehaviorMaterialization.d.ts +77 -0
- package/dist/constitution/g2BehaviorPolicyMaterializer.d.ts +48 -0
- package/dist/constitution/g2CandidateAttestation.d.ts +43 -0
- package/dist/constitution/g2Candidates.d.ts +80 -0
- package/dist/constitution/g2Drills.d.ts +33 -0
- package/dist/constitution/g3.d.ts +311 -0
- package/dist/constitution/g3Conformance.d.ts +33 -0
- package/dist/constitution/lifecycle.d.ts +25 -0
- package/dist/constitution/mutation.d.ts +15 -0
- package/dist/constitution/nodeTestEvidence.d.ts +13 -0
- package/dist/constitution/plan.d.ts +18 -0
- package/dist/constitution/policyRuntime.d.ts +5 -0
- package/dist/constitution/proof.d.ts +11 -0
- package/dist/constitution/repairPolicies.d.ts +34 -0
- package/dist/constitution/replacementFreeGit.d.ts +14 -0
- package/dist/constitution/replay.d.ts +40 -0
- package/dist/constitution/replayCache.d.ts +14 -0
- package/dist/constitution/replayWorker.d.ts +1 -0
- package/dist/constitution/repository.d.ts +129 -0
- package/dist/constitution/safeCheckout.d.ts +9 -0
- package/dist/constitution/schema.d.ts +1763 -0
- package/dist/constitution/scorecard.d.ts +219 -0
- package/dist/constitution/service.d.ts +398 -0
- package/dist/constitution/shadow.d.ts +54 -0
- package/dist/constitution/sourceMutation.d.ts +15 -0
- package/dist/constitution/staticGraphBaseline.d.ts +13 -0
- package/dist/constitution/structural.d.ts +64 -0
- package/dist/core/agenthook.d.ts +63 -0
- package/dist/core/agenthook.js +1 -0
- package/dist/core/automaticReviewMemory.d.ts +60 -0
- package/dist/core/autoreview.d.ts +66 -0
- package/dist/core/canonicalOrder.d.ts +3 -0
- package/dist/core/capturetoken.d.ts +19 -0
- package/dist/core/changeIdentity.d.ts +22 -0
- package/dist/core/changeProof.d.ts +14 -0
- package/dist/core/checkreport.d.ts +140 -0
- package/dist/core/commitrepair.d.ts +171 -0
- package/dist/core/commitrepair.js +238 -0
- package/dist/core/compare.d.ts +21 -0
- package/dist/core/config.d.ts +20 -0
- package/dist/core/conformance.d.ts +35 -0
- package/dist/core/constraintmatch.d.ts +54 -0
- package/dist/core/correction.d.ts +42 -0
- package/dist/core/correctionStage.d.ts +224 -0
- package/dist/core/declarationClusters.d.ts +149 -0
- package/dist/core/delivery.d.ts +110 -0
- package/dist/core/docanchors.d.ts +32 -0
- package/dist/core/docscan.d.ts +26 -0
- package/dist/core/drift.d.ts +13 -0
- package/dist/core/drift.js +31 -1
- package/dist/core/dupdetect.d.ts +43 -0
- package/dist/core/escalations.d.ts +129 -0
- package/dist/core/escalations.js +165 -0
- package/dist/core/events.d.ts +29 -0
- package/dist/core/evidenceMap.d.ts +164 -0
- package/dist/core/externalImports.d.ts +8 -0
- package/dist/core/format.d.ts +13 -0
- package/dist/core/glob.d.ts +9 -0
- package/dist/core/groundingLag.d.ts +84 -0
- package/dist/core/groundingLag.js +16 -2
- package/dist/core/groundingMerge.d.ts +15 -0
- package/dist/core/groundingMerge.js +95 -0
- package/dist/core/hookcache.d.ts +10 -0
- package/dist/core/hookpolicy.d.ts +47 -0
- package/dist/core/ids.d.ts +36 -0
- package/dist/core/importReview.d.ts +30 -0
- package/dist/core/io.d.ts +23 -0
- package/dist/core/jsonc.d.ts +4 -0
- package/dist/core/landscapeAdoption.d.ts +66 -0
- package/dist/core/landscapeDelivery.d.ts +76 -0
- package/dist/core/memorylog.d.ts +37 -0
- package/dist/core/migrate.d.ts +28 -0
- package/dist/core/outcomeExperience.d.ts +89 -0
- package/dist/core/overlaySafety.d.ts +24 -0
- package/dist/core/overlaySafety.js +7 -1
- package/dist/core/paths.d.ts +31 -0
- package/dist/core/pipeline.d.ts +289 -0
- package/dist/core/premises.d.ts +43 -0
- package/dist/core/provenance.d.ts +21 -0
- package/dist/core/publication.d.ts +54 -0
- package/dist/core/refrepair.d.ts +24 -0
- package/dist/core/refrepair.js +1 -1
- package/dist/core/relativeImports.d.ts +11 -0
- package/dist/core/repair.d.ts +44 -0
- package/dist/core/repairqueue.d.ts +40 -0
- package/dist/core/repairqueue.js +133 -0
- package/dist/core/reviewMemory.d.ts +40 -0
- package/dist/core/reviewqueue.d.ts +54 -0
- package/dist/core/safeRepoFile.d.ts +20 -0
- package/dist/core/served.d.ts +57 -0
- package/dist/core/served.js +14 -0
- package/dist/core/stateContract.d.ts +979 -0
- package/dist/core/stateContract.js +87 -4
- package/dist/core/stateDelivery.d.ts +78 -0
- package/dist/core/stateRecords.d.ts +383 -0
- package/dist/core/stateRecords.js +16 -1
- package/dist/core/stats.d.ts +88 -0
- package/dist/core/strictgate.d.ts +33 -0
- package/dist/core/taskReport.d.ts +226 -0
- package/dist/core/taskReport.js +514 -0
- package/dist/core/taskReportCapture.d.ts +8 -0
- package/dist/core/taskReportCapture.js +36 -0
- package/dist/core/taskReportEvidence.d.ts +26 -0
- package/dist/core/taskReportEvidence.js +268 -0
- package/dist/core/taskReportHook.d.ts +20 -0
- package/dist/core/taskReportHook.js +76 -0
- package/dist/core/taskReportPaths.d.ts +3 -0
- package/dist/core/taskReportPaths.js +23 -0
- package/dist/core/taskReportPublic.d.ts +31 -0
- package/dist/core/taskReportPublic.js +45 -0
- package/dist/core/taskReportRender.d.ts +6 -0
- package/dist/core/taskReportRender.js +97 -0
- package/dist/core/topics.d.ts +73 -0
- package/dist/core/types.d.ts +1239 -0
- package/dist/core/version.d.ts +10 -0
- package/dist/eval/guards.d.ts +45 -0
- package/dist/eval/harness.d.ts +58 -0
- package/dist/extractors/adrImport.d.ts +59 -0
- package/dist/extractors/comments.d.ts +7 -0
- package/dist/extractors/correctionSources.d.ts +11 -0
- package/dist/extractors/diff.d.ts +40 -0
- package/dist/extractors/git.d.ts +304 -0
- package/dist/extractors/git.js +208 -20
- package/dist/extractors/helm.d.ts +31 -0
- package/dist/extractors/indexer.d.ts +55 -0
- package/dist/extractors/landscapeDiscovery.d.ts +41 -0
- package/dist/extractors/languages.d.ts +77 -0
- package/dist/extractors/nativeTreeSitter.d.ts +16 -0
- package/dist/extractors/parse.d.ts +54 -0
- package/dist/extractors/php.d.ts +26 -0
- package/dist/extractors/repoSource.d.ts +53 -0
- package/dist/extractors/testreport.d.ts +36 -0
- package/dist/integrations/ciAction.d.ts +8 -0
- package/dist/integrations/claudeConfig.d.ts +44 -0
- package/dist/integrations/claudemd.d.ts +13 -0
- package/dist/integrations/claudemd.js +11 -2
- package/dist/integrations/gitignore.d.ts +16 -0
- package/dist/integrations/gitignore.js +7 -0
- package/dist/integrations/health.d.ts +74 -0
- package/dist/integrations/hooks.d.ts +41 -0
- package/dist/integrations/hooks.js +92 -66
- package/dist/integrations/madrExport.d.ts +39 -0
- package/dist/integrations/madrManifest.d.ts +69 -0
- package/dist/integrations/mergeDriver.d.ts +3 -0
- package/dist/integrations/mergeDriver.js +25 -8
- package/dist/integrations/probe.d.ts +4 -0
- package/dist/integrations/providers.d.ts +103 -0
- package/dist/integrations/scaffold.d.ts +29 -0
- package/dist/integrations/sync.d.ts +30 -0
- package/dist/integrations/sync.js +3 -2
- package/dist/integrations/team.d.ts +70 -0
- package/dist/integrations/worktree.d.ts +8 -0
- package/dist/mcp/roots.d.ts +16 -0
- package/dist/mcp/server.d.ts +36 -0
- package/dist/mcp/server.js +114 -25
- package/dist/mcp/taskReportTools.d.ts +3 -0
- package/dist/mcp/taskReportTools.js +106 -0
- package/dist/serve/app.d.ts +36 -0
- package/dist/serve/app.js +20 -0
- package/dist/serve/config.d.ts +100 -0
- package/dist/serve/writelock.d.ts +22 -0
- package/dist/store/changeLedger.d.ts +132 -0
- package/dist/store/changeLedger.js +40 -9
- package/dist/store/compact.d.ts +33 -0
- package/dist/store/db.d.ts +9 -0
- package/dist/store/embedder.d.ts +32 -0
- package/dist/store/hunchStore.d.ts +624 -0
- package/dist/store/hunchStore.js +13 -5
- package/dist/store/jsonStore.d.ts +125 -0
- package/dist/store/jsonStore.js +15 -0
- package/dist/store/merge.d.ts +39 -0
- package/dist/store/privateMigrate.d.ts +24 -0
- package/dist/store/replay.d.ts +56 -0
- package/dist/store/schema.d.ts +17 -0
- package/dist/store/stateBinding.d.ts +145 -0
- package/dist/store/stateBinding.js +110 -15
- package/dist/store/stateCapture.d.ts +15 -0
- package/dist/store/stateCapture.js +145 -0
- package/dist/synthesis/cliAdapter.d.ts +22 -0
- package/dist/synthesis/initiator.d.ts +13 -0
- package/dist/synthesis/provider.d.ts +307 -0
- package/dist/synthesis/synthesize.d.ts +117 -0
- package/dist/synthesis/tripwires.d.ts +9 -0
- package/dist/taskReports.d.ts +76 -0
- package/dist/taskReports.js +67 -0
- package/dist/wiki/adopt.d.ts +22 -0
- package/dist/wiki/graph.d.ts +87 -0
- package/dist/wiki/wiki.d.ts +242 -0
- package/package.json +6 -5
- package/server.json +2 -2
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
export declare const FILE_FIRST_DECLARATION_CLUSTER_RULE: "flat-file-anchored-semantic-clusters-v3";
|
|
2
|
+
export declare const FILE_FIRST_FILE_LIMIT = 5;
|
|
3
|
+
export declare const FILE_FIRST_CLUSTER_LIMIT = 2;
|
|
4
|
+
export declare const FILE_FIRST_MEMBER_LIMIT = 3;
|
|
5
|
+
export declare const PROGRESSIVE_DECLARATION_PLAN_RULE: "promoted-only-progressive-inspection-v4";
|
|
6
|
+
export declare const PROGRESSIVE_DECLARATION_BASELINE_LIMIT = 5;
|
|
7
|
+
export declare const PROGRESSIVE_DECLARATION_PRIMARY_LIMIT = 10;
|
|
8
|
+
export declare const PROGRESSIVE_DECLARATION_TOTAL_LIMIT = 11;
|
|
9
|
+
export declare const FILE_FIRST_DECLARATION_CLUSTER_TRANSFER: {
|
|
10
|
+
readonly benchmark: "flat-file-anchored-clusters-transfer-v3";
|
|
11
|
+
readonly scorable_tasks: 12;
|
|
12
|
+
readonly baseline_top_five_hits: 3;
|
|
13
|
+
readonly combined_hits: 6;
|
|
14
|
+
readonly combined_improvement_points: 0.25;
|
|
15
|
+
readonly baseline_file_hits: 8;
|
|
16
|
+
readonly cluster_file_hits: 10;
|
|
17
|
+
readonly rescues: 3;
|
|
18
|
+
readonly average_inspected_declarations: 18.83;
|
|
19
|
+
readonly max_inspected_declarations: 24;
|
|
20
|
+
readonly decision: "promoted-supplemental-diagnostic";
|
|
21
|
+
readonly exact_owner_policy: "disabled";
|
|
22
|
+
};
|
|
23
|
+
export declare const PROGRESSIVE_DECLARATION_DEVELOPMENT: {
|
|
24
|
+
readonly benchmark: "revealed-cluster-transfer-v1-v2-v3-replay";
|
|
25
|
+
readonly scorable_tasks: 36;
|
|
26
|
+
readonly baseline_top_five_hits: 15;
|
|
27
|
+
readonly progressive_plan_hits: 21;
|
|
28
|
+
readonly full_cluster_union_hits: 21;
|
|
29
|
+
readonly previous_average_inspected_declarations: 19.81;
|
|
30
|
+
readonly progressive_max_inspected_declarations: 11;
|
|
31
|
+
readonly inspection_reduction: 0.4446;
|
|
32
|
+
readonly decision: "candidate-awaiting-fresh-transfer";
|
|
33
|
+
readonly exact_owner_policy: "disabled";
|
|
34
|
+
};
|
|
35
|
+
export declare const PROGRESSIVE_DECLARATION_TRANSFER: {
|
|
36
|
+
readonly benchmark: "progressive-inspection-cross-repository-transfer-v4";
|
|
37
|
+
readonly scorable_tasks: 12;
|
|
38
|
+
readonly baseline_top_five_hits: 5;
|
|
39
|
+
readonly progressive_plan_hits: 5;
|
|
40
|
+
readonly full_cluster_union_hits: 5;
|
|
41
|
+
readonly rescues: 0;
|
|
42
|
+
readonly losses: 0;
|
|
43
|
+
readonly average_inspected_declarations: 11;
|
|
44
|
+
readonly previous_average_inspected_declarations: 18.92;
|
|
45
|
+
readonly inspection_reduction: 0.4185;
|
|
46
|
+
readonly decision: "retain-efficiency-advisory-v4";
|
|
47
|
+
readonly accuracy_promotion: "rejected-no-fresh-rescue";
|
|
48
|
+
readonly exact_owner_policy: "disabled";
|
|
49
|
+
};
|
|
50
|
+
export interface ClusterableDeclarationCandidate {
|
|
51
|
+
owner: string;
|
|
52
|
+
score: number;
|
|
53
|
+
runtime_declaration: boolean;
|
|
54
|
+
type_scaffolding: boolean;
|
|
55
|
+
}
|
|
56
|
+
export interface DeclarationClusterMember {
|
|
57
|
+
owner: string;
|
|
58
|
+
global_rank: number;
|
|
59
|
+
static_score: number;
|
|
60
|
+
runtime_declaration: boolean;
|
|
61
|
+
type_scaffolding: boolean;
|
|
62
|
+
}
|
|
63
|
+
export interface SemanticDeclarationCluster {
|
|
64
|
+
cluster_id: string;
|
|
65
|
+
label: string;
|
|
66
|
+
semantic_terms: string[];
|
|
67
|
+
representative: string;
|
|
68
|
+
representative_global_rank: number;
|
|
69
|
+
members: DeclarationClusterMember[];
|
|
70
|
+
members_truncated: number;
|
|
71
|
+
}
|
|
72
|
+
export interface FileFirstDeclarationCluster {
|
|
73
|
+
path: string;
|
|
74
|
+
file_rank: number;
|
|
75
|
+
file_score: number;
|
|
76
|
+
first_candidate_rank: number;
|
|
77
|
+
declaration_clusters: SemanticDeclarationCluster[];
|
|
78
|
+
}
|
|
79
|
+
export interface FileFirstDeclarationClusterReceipt {
|
|
80
|
+
version: 3;
|
|
81
|
+
receipt_id: string;
|
|
82
|
+
rule: typeof FILE_FIRST_DECLARATION_CLUSTER_RULE;
|
|
83
|
+
source_candidates: number;
|
|
84
|
+
file_limit: number;
|
|
85
|
+
cluster_limit_per_file: number;
|
|
86
|
+
member_limit_per_cluster: number;
|
|
87
|
+
selected_files: string[];
|
|
88
|
+
selected_cluster_ids: string[];
|
|
89
|
+
file_selection_strategy: "flat-shortlist-file-anchor";
|
|
90
|
+
flat_shortlist_anchor_size: 5;
|
|
91
|
+
flat_shortlist_preserved: true;
|
|
92
|
+
exact_owner_enabled: false;
|
|
93
|
+
}
|
|
94
|
+
export interface FileFirstDeclarationDiagnostic {
|
|
95
|
+
files: FileFirstDeclarationCluster[];
|
|
96
|
+
receipt: FileFirstDeclarationClusterReceipt;
|
|
97
|
+
transfer_calibration: typeof FILE_FIRST_DECLARATION_CLUSTER_TRANSFER;
|
|
98
|
+
}
|
|
99
|
+
export interface ProgressiveInspectionCandidate {
|
|
100
|
+
owner: string;
|
|
101
|
+
inspection_rank: number;
|
|
102
|
+
phase: "flat-shortlist" | "cluster-expansion" | "cluster-fallback";
|
|
103
|
+
file_path: string;
|
|
104
|
+
global_rank: number;
|
|
105
|
+
cluster_id: string | null;
|
|
106
|
+
cluster_label: string | null;
|
|
107
|
+
runtime_declaration: boolean;
|
|
108
|
+
type_scaffolding: boolean;
|
|
109
|
+
}
|
|
110
|
+
export interface ProgressiveInspectionPhase {
|
|
111
|
+
phase: ProgressiveInspectionCandidate["phase"];
|
|
112
|
+
instruction: string;
|
|
113
|
+
stop_condition: string;
|
|
114
|
+
candidates: ProgressiveInspectionCandidate[];
|
|
115
|
+
}
|
|
116
|
+
export interface ProgressiveDeclarationPlanReceipt {
|
|
117
|
+
version: 1;
|
|
118
|
+
receipt_id: string;
|
|
119
|
+
rule: typeof PROGRESSIVE_DECLARATION_PLAN_RULE;
|
|
120
|
+
baseline_limit: number;
|
|
121
|
+
primary_limit: number;
|
|
122
|
+
total_limit: number;
|
|
123
|
+
selected_owners: string[];
|
|
124
|
+
selected_cluster_ids: string[];
|
|
125
|
+
promoted_mechanisms: readonly ["repository-adaptive-ranking", "flat-file-anchored-semantic-clusters"];
|
|
126
|
+
rejected_rerankers_disabled: true;
|
|
127
|
+
flat_shortlist_preserved: true;
|
|
128
|
+
exact_owner_enabled: false;
|
|
129
|
+
}
|
|
130
|
+
export interface ProgressiveDeclarationPlan {
|
|
131
|
+
phases: ProgressiveInspectionPhase[];
|
|
132
|
+
candidates: ProgressiveInspectionCandidate[];
|
|
133
|
+
receipt: ProgressiveDeclarationPlanReceipt;
|
|
134
|
+
development_calibration: typeof PROGRESSIVE_DECLARATION_DEVELOPMENT;
|
|
135
|
+
transfer_calibration: typeof PROGRESSIVE_DECLARATION_TRANSFER;
|
|
136
|
+
}
|
|
137
|
+
/** Build a hierarchical diagnostic from the existing static ranking. The flat
|
|
138
|
+
* shortlist remains untouched: this view collapses related declaration
|
|
139
|
+
* scaffolding into semantic families so one noisy family cannot consume every
|
|
140
|
+
* inspection slot inside a promising file. It is still a candidate view, not
|
|
141
|
+
* an exact-owner claim. */
|
|
142
|
+
export declare function buildFileFirstDeclarationClusters(rankedCandidatesValue: ClusterableDeclarationCandidate[], requestedFileLimit?: number, requestedClusterLimit?: number, requestedMemberLimit?: number): FileFirstDeclarationDiagnostic;
|
|
143
|
+
/** Turn the promoted flat shortlist and semantic clusters into a progressive
|
|
144
|
+
* inspection queue. The first five candidates remain byte-for-byte intact.
|
|
145
|
+
* Supplemental candidates must already belong to a selected semantic family,
|
|
146
|
+
* and are ordered by the frozen repository-adaptive rank instead of widening
|
|
147
|
+
* to every declaration in the file. The last slot is explicitly a fallback so
|
|
148
|
+
* callers can stop after ten inspections when the behavior is already owned. */
|
|
149
|
+
export declare function buildProgressiveDeclarationPlan(rankedCandidatesValue: ClusterableDeclarationCandidate[], clusters: FileFirstDeclarationDiagnostic, requestedBaselineLimit?: number, requestedTotalLimit?: number): ProgressiveDeclarationPlan;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { AssembledContext } from "../store/hunchStore.js";
|
|
2
|
+
import type { Component, Decision, Symbol } from "./types.js";
|
|
3
|
+
import type { ExecutionObligation } from "./pipeline.js";
|
|
4
|
+
import { type LandscapeDeliveryFragment } from "./landscapeDelivery.js";
|
|
5
|
+
export declare const DELIVERY_ENVELOPE_SCHEMA_VERSION: "hunch.delivery-envelope/1";
|
|
6
|
+
export declare const DELIVERY_PROFILE_POLICY_VERSION: "hunch.delivery-profile/1";
|
|
7
|
+
export declare const DELIVERY_PROFILES: readonly ["builder", "reviewer", "architect"];
|
|
8
|
+
export type DeliveryProfile = (typeof DELIVERY_PROFILES)[number];
|
|
9
|
+
export type DeliveryKind = "constraints" | "decisions" | "bugs" | "findings" | "resources" | "relationships";
|
|
10
|
+
export type CommitReachability = "reachable" | "unreachable" | "unknown";
|
|
11
|
+
export interface DeliveryRef {
|
|
12
|
+
kind: DeliveryKind;
|
|
13
|
+
record_id: string;
|
|
14
|
+
}
|
|
15
|
+
export type DeliveryReason = "ranked" | "blocking-reserved";
|
|
16
|
+
export type DeliveryProvenanceStatus = "current" | "unverified" | "stale";
|
|
17
|
+
export interface DeliveredItem extends DeliveryRef {
|
|
18
|
+
/** One-based position in the eligible memory ranking. */
|
|
19
|
+
rank: number;
|
|
20
|
+
delivery_reason: DeliveryReason;
|
|
21
|
+
provenance_status: DeliveryProvenanceStatus;
|
|
22
|
+
/** Deterministic approximation: four Unicode code points per token. */
|
|
23
|
+
token_cost: number;
|
|
24
|
+
}
|
|
25
|
+
export interface DeliverySupplement {
|
|
26
|
+
id: string;
|
|
27
|
+
kind: string;
|
|
28
|
+
text: string;
|
|
29
|
+
/** Higher values are attempted first after ranked memory. */
|
|
30
|
+
priority?: number;
|
|
31
|
+
}
|
|
32
|
+
export interface DeliveredSupplement {
|
|
33
|
+
id: string;
|
|
34
|
+
kind: string;
|
|
35
|
+
delivered: boolean;
|
|
36
|
+
reason: "supplemental" | "budget" | "empty" | "abstained";
|
|
37
|
+
rank: number;
|
|
38
|
+
token_cost: number;
|
|
39
|
+
}
|
|
40
|
+
export interface DeliveryOmission extends DeliveryRef {
|
|
41
|
+
reason: "budget" | "stale-provenance" | "retired" | "actionability-cap" | "endpoint-not-delivered" | "landscape-cap" | "profile-cap" | DeliveryAbstentionReason;
|
|
42
|
+
detail: string;
|
|
43
|
+
}
|
|
44
|
+
export type DeliveryAbstentionReason = "low-confidence" | "insufficient-context" | "low-relevance";
|
|
45
|
+
export interface DeliveryAbstention {
|
|
46
|
+
/** True when Hunch found prescriptive memory but deliberately withheld it. */
|
|
47
|
+
active: boolean;
|
|
48
|
+
withheld: number;
|
|
49
|
+
reasons: Record<DeliveryAbstentionReason, number>;
|
|
50
|
+
/** A concrete recovery path instead of a silent empty result. */
|
|
51
|
+
retry_hint: string | null;
|
|
52
|
+
}
|
|
53
|
+
/** A bounded, falsifiable interpretation of one delivered decision. The packet
|
|
54
|
+
* is derived only from stored record/query fields; it never invents a fix. */
|
|
55
|
+
export interface DeliveryHypothesis {
|
|
56
|
+
kind: "decision";
|
|
57
|
+
record_id: string;
|
|
58
|
+
/** Rank of the corresponding delivered record in this envelope. */
|
|
59
|
+
rank: number;
|
|
60
|
+
why: string;
|
|
61
|
+
where: string[];
|
|
62
|
+
historical_pattern: string;
|
|
63
|
+
verify: string;
|
|
64
|
+
disprove: string;
|
|
65
|
+
/** Observable controller checks derived from immutable record evidence. */
|
|
66
|
+
obligations: ExecutionObligation[];
|
|
67
|
+
}
|
|
68
|
+
export interface DeliveryEnvelope {
|
|
69
|
+
schema_version: typeof DELIVERY_ENVELOPE_SCHEMA_VERSION;
|
|
70
|
+
/** Role-specific ordering only; never enforcement or authority. */
|
|
71
|
+
profile: DeliveryProfile;
|
|
72
|
+
ranking_policy: typeof DELIVERY_PROFILE_POLICY_VERSION;
|
|
73
|
+
/** Content-addressed identity for exactly what this envelope returned. */
|
|
74
|
+
receipt_id: string;
|
|
75
|
+
text: string;
|
|
76
|
+
delivered: DeliveredItem[];
|
|
77
|
+
hypotheses: DeliveryHypothesis[];
|
|
78
|
+
obligations: ExecutionObligation[];
|
|
79
|
+
supplements: DeliveredSupplement[];
|
|
80
|
+
omitted: DeliveryOmission[];
|
|
81
|
+
/** Reviewed graph records delivered through this same budget and receipt. */
|
|
82
|
+
landscape: LandscapeDeliveryFragment | null;
|
|
83
|
+
budget_tokens: number;
|
|
84
|
+
used_chars: number;
|
|
85
|
+
/** Conservative text + structured landscape payload accounting. */
|
|
86
|
+
accounted_chars: number;
|
|
87
|
+
/** True only when the requested budget is mathematically too small to name
|
|
88
|
+
* every active blocking invariant. Safety wins, and the overflow is explicit. */
|
|
89
|
+
blocking_overflow: boolean;
|
|
90
|
+
abstention: DeliveryAbstention;
|
|
91
|
+
}
|
|
92
|
+
export interface DeliveryOptions {
|
|
93
|
+
/** Defaults to builder for day-to-day coding work. */
|
|
94
|
+
profile?: DeliveryProfile;
|
|
95
|
+
root?: string;
|
|
96
|
+
symbols?: readonly Pick<Symbol, "id" | "name" | "file">[];
|
|
97
|
+
components?: readonly Pick<Component, "id" | "status" | "paths">[];
|
|
98
|
+
/** Full decision corpus lets the envelope explain only decisions it actually delivered. */
|
|
99
|
+
decisionCorpus?: readonly Decision[];
|
|
100
|
+
/** Caller-specific grounding that must share the same hard output budget. */
|
|
101
|
+
supplements?: readonly DeliverySupplement[];
|
|
102
|
+
/** Time-travel contexts intentionally include records that are retired at HEAD. */
|
|
103
|
+
historical?: boolean;
|
|
104
|
+
/** Injectable for deterministic tests. Omit to use the local Git graph. */
|
|
105
|
+
commitReachability?: (commit: string) => CommitReachability;
|
|
106
|
+
}
|
|
107
|
+
/** Validate the public receipt without trusting a caller-supplied identity. */
|
|
108
|
+
export declare function assertDeliveryEnvelope(envelope: DeliveryEnvelope): void;
|
|
109
|
+
/** Build the one envelope used by CLI, MCP, and the edit hook. */
|
|
110
|
+
export declare function buildDeliveryEnvelope(ctx: AssembledContext, options?: DeliveryOptions): DeliveryEnvelope;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown topic anchors — decision-grounding for PROSE (the doc≠graph spoke,
|
|
3
|
+
* extended to the files the ecosystem already funnels team knowledge into:
|
|
4
|
+
* AGENTS.md, CLAUDE.md, docs/*.md).
|
|
5
|
+
*
|
|
6
|
+
* A tracked markdown file declares which decision topic a section describes:
|
|
7
|
+
*
|
|
8
|
+
* <!-- hunch:topic auth.session --> grounding only
|
|
9
|
+
* <!-- hunch:topic auth.session dec_a1b2c3d4e5 --> PINNED: prose written against that decision
|
|
10
|
+
*
|
|
11
|
+
* Deterministic by construction: drift fires ONLY on an explicit pin whose
|
|
12
|
+
* decision has been superseded — never on a semantic guess (the same philosophy
|
|
13
|
+
* as `anchor-stale` in drift.ts). Unpinned markers still ground the pre-edit
|
|
14
|
+
* hook but can never fire drift.
|
|
15
|
+
*/
|
|
16
|
+
import type { Decision } from "./types.js";
|
|
17
|
+
export interface DocAnchor {
|
|
18
|
+
topic: string;
|
|
19
|
+
/** The decision id the prose was written against, or null for an unpinned marker. */
|
|
20
|
+
pin: string | null;
|
|
21
|
+
/** 1-based line of the marker in the document. */
|
|
22
|
+
line: number;
|
|
23
|
+
}
|
|
24
|
+
/** Parse every hunch:topic marker out of a markdown document. Markers inside
|
|
25
|
+
* fenced code blocks or inline code spans are examples, not declarations,
|
|
26
|
+
* and are skipped. */
|
|
27
|
+
export declare function parseDocAnchors(text: string): DocAnchor[];
|
|
28
|
+
/** Pre-edit grounding for a markdown document that carries topic anchors: the
|
|
29
|
+
* CURRENT decision per declared topic (graph over prose), what it rejected,
|
|
30
|
+
* and a stale-pin warning the editor can heal inline. Empty when no anchor
|
|
31
|
+
* resolves to a decision. */
|
|
32
|
+
export declare function renderDocGrounding(anchors: readonly DocAnchor[], decisions: readonly Decision[]): string;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Decision } from "./types.js";
|
|
2
|
+
export declare const STALE_MARKER: RegExp;
|
|
3
|
+
export declare const SRC_REF: RegExp;
|
|
4
|
+
/** Bounded walk for repo markdown (root + docs/, depth-limited; heavy/irrelevant trees skipped). */
|
|
5
|
+
export declare function markdownDocs(root: string): Array<{
|
|
6
|
+
path: string;
|
|
7
|
+
rel: string;
|
|
8
|
+
}>;
|
|
9
|
+
export type DocStatus = "grounded" | "stale" | "unverified";
|
|
10
|
+
export interface RepoDoc {
|
|
11
|
+
/** repo-relative POSIX path. */
|
|
12
|
+
rel: string;
|
|
13
|
+
/** First `# ` heading, or the path when the doc has none. */
|
|
14
|
+
title: string;
|
|
15
|
+
/** Topics the doc declares via hunch:topic markers. */
|
|
16
|
+
topics: string[];
|
|
17
|
+
/** src/*.ts files the doc mentions (the component-association signal). */
|
|
18
|
+
srcRefs: string[];
|
|
19
|
+
status: DocStatus;
|
|
20
|
+
/** Human-readable reasons behind a "stale" grade (empty otherwise). */
|
|
21
|
+
issues: string[];
|
|
22
|
+
}
|
|
23
|
+
/** Grade every repo doc. GENERATED wiki pages (hunch:wiki header) are views of
|
|
24
|
+
* the graph, not specs — they are excluded here and freshness-gated by their
|
|
25
|
+
* own manifest hash instead. */
|
|
26
|
+
export declare function scanRepoDocs(decisions: readonly Decision[], root: string): RepoDoc[];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { HunchStore } from "../store/hunchStore.js";
|
|
2
|
+
export type DriftKind = "dead-ref" | "supersede" | "doc-stale" | "anchor-stale" | "doc-anchor-stale" | "doc-anchor-dangling" | "wiki-stale" | "finding-stale" | "premise-stale" | "commit-unresolvable" | "madr-stale" | "madr-edited" | "madr-orphan";
|
|
3
|
+
export interface DriftFinding {
|
|
4
|
+
kind: DriftKind;
|
|
5
|
+
id: string;
|
|
6
|
+
detail: string;
|
|
7
|
+
}
|
|
8
|
+
export interface DriftReport {
|
|
9
|
+
findings: DriftFinding[];
|
|
10
|
+
}
|
|
11
|
+
export declare function computeDrift(store: HunchStore, root: string, deps?: {
|
|
12
|
+
commitResolvable?: (sha: string) => boolean;
|
|
13
|
+
}): DriftReport;
|
package/dist/core/drift.js
CHANGED
|
@@ -26,7 +26,8 @@ import { parseDocAnchors } from "./docanchors.js";
|
|
|
26
26
|
import { markdownDocs, STALE_MARKER, SRC_REF } from "./docscan.js";
|
|
27
27
|
import { computeWikiDrift } from "../wiki/wiki.js";
|
|
28
28
|
import { computeMadrDrift } from "../integrations/madrManifest.js";
|
|
29
|
-
|
|
29
|
+
import { commitsExist, isGitRepo } from "../extractors/git.js";
|
|
30
|
+
export function computeDrift(store, root, deps = {}) {
|
|
30
31
|
const findings = [];
|
|
31
32
|
const decisions = store.recs("decisions");
|
|
32
33
|
const byId = new Map(decisions.map((d) => [d.id, d]));
|
|
@@ -46,6 +47,25 @@ export function computeDrift(store, root) {
|
|
|
46
47
|
return liveFiles.has(p) || liveDirs.some((dir) => p.startsWith(dir));
|
|
47
48
|
};
|
|
48
49
|
const premiseEnv = { now: new Date().toISOString(), exists: (p) => existsSync(join(root, p)) };
|
|
50
|
+
// A plain existence check is meaningless outside a git repo — computed once,
|
|
51
|
+
// not per decision, and never a false positive for a directory that merely
|
|
52
|
+
// happens to hold .hunch/ without being a git checkout. Injectable so tests
|
|
53
|
+
// (and callers with a cheaper oracle) never have to shell out per decision.
|
|
54
|
+
const gitRepo = isGitRepo(root);
|
|
55
|
+
// One batched `git cat-file --batch-check` for every commit-bearing decision,
|
|
56
|
+
// not one `rev-parse` per decision — skipped entirely when a predicate is
|
|
57
|
+
// injected (tests/callers with a cheaper oracle never pay for this at all).
|
|
58
|
+
const resolvableCommits = gitRepo && !deps.commitResolvable
|
|
59
|
+
? commitsExist([...new Set(decisions.filter((d) => d.commit).map((d) => d.commit))], root)
|
|
60
|
+
: null;
|
|
61
|
+
const defaultCommitResolvable = (sha) => {
|
|
62
|
+
if (!gitRepo)
|
|
63
|
+
return true; // never flag outside a git repo
|
|
64
|
+
if (resolvableCommits === null)
|
|
65
|
+
return true; // the batch check itself failed, or was skipped — fail open
|
|
66
|
+
return resolvableCommits.has(sha);
|
|
67
|
+
};
|
|
68
|
+
const commitResolvable = deps.commitResolvable ?? defaultCommitResolvable;
|
|
49
69
|
for (const d of decisions) {
|
|
50
70
|
// 1. DEAD-REFERENCE — only for in-force decisions; a superseded one referencing
|
|
51
71
|
// a since-deleted file is legitimate history, not drift.
|
|
@@ -58,6 +78,16 @@ export function computeDrift(store, root) {
|
|
|
58
78
|
findings.push({ kind: "dead-ref", id: d.id, detail: `references missing file "${f}"` });
|
|
59
79
|
}
|
|
60
80
|
}
|
|
81
|
+
// 8. COMMIT-UNRESOLVABLE — an in-force decision's commit provenance no longer
|
|
82
|
+
// resolves at all (source branch gone + gc'd past recovery). The
|
|
83
|
+
// opportunistic post-merge repair (commitrepair.ts) is the fix path; this
|
|
84
|
+
// is purely the "nothing caught it" signal — deterministic, never auto-fixed.
|
|
85
|
+
// Mirrors repair.ts:59's live-records-only rule: `inForce` alone doesn't
|
|
86
|
+
// exclude a never-adopted "rejected" decision (superseded_by is null for
|
|
87
|
+
// those too), so exclude it explicitly here.
|
|
88
|
+
if (d.commit && d.status !== "rejected" && !commitResolvable(d.commit)) {
|
|
89
|
+
findings.push({ kind: "commit-unresolvable", id: d.id, detail: `commit ${d.commit} no longer resolves in this repository — provenance may need manual repair` });
|
|
90
|
+
}
|
|
61
91
|
}
|
|
62
92
|
// 2. SUPERSEDE-INTEGRITY — a contradiction class: A.supersedes = B, but B is
|
|
63
93
|
// either gone or still in force (the private-supersede bug shape).
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic near-duplicate detection for auto-drafted decisions — hygiene,
|
|
3
|
+
* not judgment (the human vouch stays untouchable; dec_a466655539 doctrine).
|
|
4
|
+
*
|
|
5
|
+
* The duplicate factory: a human records a decision via MCP (commit: null),
|
|
6
|
+
* then commits the code — the post-commit hook synthesizes a SECOND record of
|
|
7
|
+
* the same choice under a commit-keyed id. Review triage showed 7 of 14 queued
|
|
8
|
+
* drafts were exactly this.
|
|
9
|
+
*
|
|
10
|
+
* Two layers, both model-free:
|
|
11
|
+
* - commitCoveredBy(): PRE-draft gate in syncCommit — a recent human-confirmed
|
|
12
|
+
* decision already claims this commit's files (+ subject terms) → skip the
|
|
13
|
+
* draft entirely (also saves the subscription call). Recency-windowed so an
|
|
14
|
+
* OLD decision on the same files can never suppress genuinely new work.
|
|
15
|
+
* - draftDuplicateOf(): review-time flag for drafts already in the store —
|
|
16
|
+
* full-text term overlap + file overlap against accepted records, so
|
|
17
|
+
* `hunch review` marks likely duplicates and can batch-reject them.
|
|
18
|
+
*/
|
|
19
|
+
import type { Decision } from "./types.js";
|
|
20
|
+
/** Lowercased salient terms (≥4 chars, non-stopword) — deliberately simple and
|
|
21
|
+
* deterministic; shared by both layers so their notion of "similar" agrees. */
|
|
22
|
+
export declare function dupTerms(text: string): Set<string>;
|
|
23
|
+
export interface Coverage {
|
|
24
|
+
id: string;
|
|
25
|
+
title: string;
|
|
26
|
+
hoursAgo: number;
|
|
27
|
+
fileOverlapPct: number;
|
|
28
|
+
}
|
|
29
|
+
/** Does a RECENT human-confirmed live decision already claim this commit's
|
|
30
|
+
* files (and roughly its subject)? Deterministic pre-draft gate. */
|
|
31
|
+
export declare function commitCoveredBy(codeFiles: readonly string[], subject: string, existing: readonly Decision[], nowMs: number): Coverage | null;
|
|
32
|
+
export interface DupMatch {
|
|
33
|
+
of: Decision;
|
|
34
|
+
/** 0..1 combined similarity (term Jaccard, file-overlap boosted). */
|
|
35
|
+
score: number;
|
|
36
|
+
}
|
|
37
|
+
/** Only a finalized, still-live human decision can justify deleting a draft as
|
|
38
|
+
* redundant. Proposed records may resemble one another, but choosing which one
|
|
39
|
+
* survives is review judgment—not deterministic hygiene. */
|
|
40
|
+
export declare function isAcceptedDuplicateAnchor(d: Decision): boolean;
|
|
41
|
+
/** Is an existing DRAFT a near-duplicate of an accepted record? Review-time
|
|
42
|
+
* flag; threshold callers use 0.35 (batch-reject) — conservative on purpose. */
|
|
43
|
+
export declare function draftDuplicateOf(draft: Decision, existing: readonly Decision[]): DupMatch | null;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inline escalations — the "ask the human IN THE PROMPT, not in a background queue"
|
|
3
|
+
* half of the auto-trust model.
|
|
4
|
+
*
|
|
5
|
+
* Captured memory auto-trusts the moment it lands (status accepted, advisory), so
|
|
6
|
+
* there is no draft queue to drain. The only things that still need a human are the
|
|
7
|
+
* rare cases the graph genuinely CANNOT resolve on its own — and those are surfaced
|
|
8
|
+
* as a short, question-framed list the assistant raises in conversation at the
|
|
9
|
+
* moment, then normally EMPTY.
|
|
10
|
+
*
|
|
11
|
+
* Deterministic only. Memory questions include a topic conflict (>1 live decision for
|
|
12
|
+
* one topic — a git merge can create these; see topics.topicCollisions) and one
|
|
13
|
+
* exact imported ADR awaiting a hash-bound approve/decline answer. We do NOT
|
|
14
|
+
* guess semantically which un-anchored decisions "contradict" each other — that
|
|
15
|
+
* stays the assistant's judgment, asked in chat, never a machine verdict (same
|
|
16
|
+
* explicit-anchors-only ethos as the drift detector).
|
|
17
|
+
*
|
|
18
|
+
* Pure over a Decision[] — no store, no IO — so the CLI, the MCP read tool, and the
|
|
19
|
+
* session-start orientation all share one source of truth.
|
|
20
|
+
*/
|
|
21
|
+
import type { Decision } from "./types.js";
|
|
22
|
+
import { type CommitRewrite } from "./commitrepair.js";
|
|
23
|
+
export type EscalationKind = "topic-conflict" | "imported-adr-review" | "policy-candidate" | "policy-proposal" | "policy-repaired" | "premise-stale" | "commit-repair-pending";
|
|
24
|
+
export interface Escalation {
|
|
25
|
+
kind: EscalationKind;
|
|
26
|
+
/** the topic (or other key) the conflict is about. */
|
|
27
|
+
topic: string;
|
|
28
|
+
/** the decisions the human must choose between. */
|
|
29
|
+
decisionIds: string[];
|
|
30
|
+
/** a one-line, human-facing question the assistant should raise in the prompt. */
|
|
31
|
+
question: string;
|
|
32
|
+
/** the supporting detail (ids + titles) for the question. */
|
|
33
|
+
detail: string;
|
|
34
|
+
/** the concrete resolution the human's answer maps to. */
|
|
35
|
+
resolution: string;
|
|
36
|
+
/** false ONLY for an entry whose own resolution requires acting on a
|
|
37
|
+
* DIFFERENT entry first (a duplicate-id queue's non-drop, non-apply
|
|
38
|
+
* follower) — it still surfaces, for transparency, but gating surfaces
|
|
39
|
+
* (CI exit code, "needs your call" tallies) must not count it: resolving
|
|
40
|
+
* the actionable entry ahead of it is what clears it, not anything a
|
|
41
|
+
* human can do to this row directly (#61). Omitted (undefined) means
|
|
42
|
+
* true — every other escalation kind is always directly actionable. */
|
|
43
|
+
actionable?: boolean;
|
|
44
|
+
}
|
|
45
|
+
/** Escalations gating surfaces (CI exit codes, "needs your call" counts/lists)
|
|
46
|
+
* should act on: everything except an entry explicitly marked
|
|
47
|
+
* actionable:false (#61). The full list — including non-actionable
|
|
48
|
+
* entries — still belongs in any transparency-facing output (e.g. --json). */
|
|
49
|
+
export declare function actionableEscalations(items: readonly Escalation[]): Escalation[];
|
|
50
|
+
export interface EscalationSummary {
|
|
51
|
+
/** the subset a gating surface should count/exit/ask on. */
|
|
52
|
+
actionable: Escalation[];
|
|
53
|
+
/** how many entries were filtered out — informational-only, shown for
|
|
54
|
+
* transparency but not itself a decision to raise. */
|
|
55
|
+
context: number;
|
|
56
|
+
}
|
|
57
|
+
/** One computation for every "N need your call (+M shown for context)"
|
|
58
|
+
* consumer (CLI `escalations`, SessionStart, the `hunch_now`/`hunch_escalations`
|
|
59
|
+
* MCP tools) — introduced alongside `actionable` (#61) specifically so a
|
|
60
|
+
* future consumer of Escalation[] can't repeat the mistake of hand-rolling
|
|
61
|
+
* the filter and forgetting it (the VS Code panel did, before this existed). */
|
|
62
|
+
export declare function summarizeEscalations(items: readonly Escalation[]): EscalationSummary;
|
|
63
|
+
/** "you" (the CLI, talking directly to the operator) vs "mcp" (an assistant
|
|
64
|
+
* relaying a question to the human, third person). */
|
|
65
|
+
export type EscalationAudience = "cli" | "mcp";
|
|
66
|
+
/** The ONE "N need your call (+M shown for context)" headline, shared by the
|
|
67
|
+
* CLI `escalations` command and the `hunch_escalations` MCP tool (#61) —
|
|
68
|
+
* including its own "nothing actionable, but N item(s) queued for context"
|
|
69
|
+
* fallback, so that unreachable-today prose exists in exactly one place
|
|
70
|
+
* instead of being hand-copied per consumer (the copy-paste is how the VS
|
|
71
|
+
* Code panel missed the filter entirely before `actionable` existed).
|
|
72
|
+
* Callers are expected to have already special-cased `items.length === 0`
|
|
73
|
+
* (a plainer "nothing needs your decision" message, no tally at all). */
|
|
74
|
+
export declare function escalationHeadline(items: readonly Escalation[], audience: EscalationAudience): string;
|
|
75
|
+
/** The decisions a human must make NOW, to be asked INLINE. Empty in a healthy graph. */
|
|
76
|
+
export declare function pendingEscalations(decisions: readonly Decision[]): Escalation[];
|
|
77
|
+
/** A commit-provenance repair the post-merge hook detected and queued
|
|
78
|
+
* (src/core/repairqueue.ts) but never applied — the match signal (related_files
|
|
79
|
+
* overlap) isn't strong enough to write unattended, so it's a question for the
|
|
80
|
+
* human, exactly like every other entry here, never a silent write.
|
|
81
|
+
*
|
|
82
|
+
* `decisions` is the caller's VISIBLE scope (supplies the title only) —
|
|
83
|
+
* MCP/SessionStart pass store.advisoryRecs(), which is public-only in
|
|
84
|
+
* private mode. `live` is the scope liveRewrites checks the repair against;
|
|
85
|
+
* it defaults to `decisions` but callers on an advisory scope must pass the
|
|
86
|
+
* FULL store (store.recs()) here, since repair-provenance itself reads the
|
|
87
|
+
* full store — an overlay decision's repair is fully answerable even where
|
|
88
|
+
* its title isn't visible, and must not go silent just because the title is
|
|
89
|
+
* private.
|
|
90
|
+
*
|
|
91
|
+
* `withheld` (from repairqueue.ts's withheldRewrites — a git-facing check
|
|
92
|
+
* this module deliberately stays free of, so the caller runs it and passes
|
|
93
|
+
* the result in) names entries whose proposed `to` doesn't resolve to a
|
|
94
|
+
* real commit here. `--apply --only <id>` can never resolve one of these —
|
|
95
|
+
* advertising it as the answer would be advice guaranteed to no-op
|
|
96
|
+
* forever, which is worse than not asking at all. Such an entry still
|
|
97
|
+
* needs a human (only `--drop` can retire it), so it still escalates, just
|
|
98
|
+
* with wording that doesn't promise `--apply` will help.
|
|
99
|
+
*
|
|
100
|
+
* Keyed by OBJECT, not by id, matching withheldForUnresolvableTo's own
|
|
101
|
+
* contract: a corrupted queue file can carry two entries sharing an id
|
|
102
|
+
* (one resolvable, one not) — an id-keyed set couldn't tell them apart and
|
|
103
|
+
* would wrongly tag the resolvable sibling as unresolvable too. Every
|
|
104
|
+
* caller of this function already passes the SAME `queued` array to both
|
|
105
|
+
* this function and withheldRewrites, so identity holds. */
|
|
106
|
+
export declare function commitRepairEscalations(queued: readonly CommitRewrite[], decisions: readonly Decision[], live?: readonly Decision[], withheld?: ReadonlySet<CommitRewrite>): Escalation[];
|
|
107
|
+
/** The minimal policy shape the escalation scan needs — a structural subset of
|
|
108
|
+
* constitution PolicySpec, so this module stays dependency-free of the
|
|
109
|
+
* Constitution schemas (core must not import constitution). */
|
|
110
|
+
export interface PolicyLite {
|
|
111
|
+
id: string;
|
|
112
|
+
state: string;
|
|
113
|
+
statement: string;
|
|
114
|
+
proof: string | null;
|
|
115
|
+
authority: unknown;
|
|
116
|
+
activation_gate?: {
|
|
117
|
+
kind: string;
|
|
118
|
+
status: string;
|
|
119
|
+
reason: string;
|
|
120
|
+
} | null;
|
|
121
|
+
/** the policy's most recent audit action, when the caller has it — lets the
|
|
122
|
+
* scan surface auto-repaired policies that need a fresh proof. */
|
|
123
|
+
last_action?: string | null;
|
|
124
|
+
}
|
|
125
|
+
/** The Constitution's genuine human moments (§59.5.3), framed as inline questions:
|
|
126
|
+
* a candidate awaiting review, and a proposed policy whose next step (prove, or
|
|
127
|
+
* accept/reject) is a human call. Machine conclusions never appear here as
|
|
128
|
+
* approvals — every entry is a QUESTION with its explicit resolution verb. */
|
|
129
|
+
export declare function policyEscalations(policies: readonly PolicyLite[]): Escalation[];
|