instar 1.3.712 → 1.3.714
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/.claude/skills/autonomous/SKILL.md +49 -0
- package/.claude/skills/autonomous/hooks/autonomous-stop-hook.sh +103 -9
- package/.claude/skills/autonomous/scripts/setup-autonomous.sh +47 -0
- package/dist/commands/init.js +9 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/config/ConfigDefaults.d.ts.map +1 -1
- package/dist/config/ConfigDefaults.js +19 -0
- package/dist/config/ConfigDefaults.js.map +1 -1
- package/dist/core/AutonomousRunStore.d.ts +200 -0
- package/dist/core/AutonomousRunStore.d.ts.map +1 -0
- package/dist/core/AutonomousRunStore.js +402 -0
- package/dist/core/AutonomousRunStore.js.map +1 -0
- package/dist/core/CompletionEvaluator.d.ts +24 -0
- package/dist/core/CompletionEvaluator.d.ts.map +1 -1
- package/dist/core/CompletionEvaluator.js +29 -1
- package/dist/core/CompletionEvaluator.js.map +1 -1
- package/dist/core/ExternalOperationGate.d.ts.map +1 -1
- package/dist/core/ExternalOperationGate.js +6 -0
- package/dist/core/ExternalOperationGate.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts +1 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +56 -3
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/ScopeAccretionCorroboration.d.ts +79 -0
- package/dist/core/ScopeAccretionCorroboration.d.ts.map +1 -0
- package/dist/core/ScopeAccretionCorroboration.js +159 -0
- package/dist/core/ScopeAccretionCorroboration.js.map +1 -0
- package/dist/core/ScopeAccretionRatifier.d.ts +93 -0
- package/dist/core/ScopeAccretionRatifier.d.ts.map +1 -0
- package/dist/core/ScopeAccretionRatifier.js +228 -0
- package/dist/core/ScopeAccretionRatifier.js.map +1 -0
- package/dist/core/ScopeAccretionSweep.d.ts +83 -0
- package/dist/core/ScopeAccretionSweep.d.ts.map +1 -0
- package/dist/core/ScopeAccretionSweep.js +353 -0
- package/dist/core/ScopeAccretionSweep.js.map +1 -0
- package/dist/core/WorkingSetManifest.d.ts.map +1 -1
- package/dist/core/WorkingSetManifest.js +26 -1
- package/dist/core/WorkingSetManifest.js.map +1 -1
- package/dist/core/installCodexHooks.d.ts.map +1 -1
- package/dist/core/installCodexHooks.js +9 -0
- package/dist/core/installCodexHooks.js.map +1 -1
- package/dist/core/types.d.ts +29 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/lifeline/TelegramLifeline.d.ts.map +1 -1
- package/dist/lifeline/TelegramLifeline.js +8 -0
- package/dist/lifeline/TelegramLifeline.js.map +1 -1
- package/dist/messaging/TelegramAdapter.d.ts +18 -0
- package/dist/messaging/TelegramAdapter.d.ts.map +1 -1
- package/dist/messaging/TelegramAdapter.js +28 -0
- package/dist/messaging/TelegramAdapter.js.map +1 -1
- package/dist/scaffold/templates.js +2 -2
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +638 -1
- package/dist/server/routes.js.map +1 -1
- package/dist/server/specReviewRoutes.d.ts +6 -0
- package/dist/server/specReviewRoutes.d.ts.map +1 -1
- package/dist/server/specReviewRoutes.js +30 -0
- package/dist/server/specReviewRoutes.js.map +1 -1
- package/package.json +1 -1
- package/scripts/lint-scrape-fixture-realness.js +40 -0
- package/src/data/builtin-manifest.json +65 -65
- package/src/scaffold/templates.ts +2 -2
- package/upgrades/1.3.713.md +65 -0
- package/upgrades/1.3.714.md +40 -0
- package/upgrades/side-effects/autonomous-scope-accretion-completion.md +77 -0
- package/upgrades/side-effects/bench-prompt-fixes-2.md +72 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ScopeAccretionCorroboration — per-class deterministic "built/delivered"
|
|
3
|
+
* evidence, computed server-side at judge-fire time.
|
|
4
|
+
*
|
|
5
|
+
* Spec: docs/specs/autonomous-scope-accretion-completion.md §2.5
|
|
6
|
+
* (R21/R22/R32/R33/R34). An accreted deliverable clears ONLY by:
|
|
7
|
+
* - spec class: the convergence REPORT artifact + a server-recorded
|
|
8
|
+
* conformance-check invocation inside the run window (R32), OR a merged PR
|
|
9
|
+
* passing the exact predicate (R33);
|
|
10
|
+
* - audit/runbook/incident doc: a merged PR containing the file (own-file
|
|
11
|
+
* rule relaxed for a doc whose deliverable IS the doc);
|
|
12
|
+
* - script: a merged PR touching the script path;
|
|
13
|
+
* - the local-git POSITIVE-ONLY shortcut (R34): the path verifiably landed on
|
|
14
|
+
* `origin/main` after the start SHA — may CLEAR, never used to refuse.
|
|
15
|
+
*
|
|
16
|
+
* Cost discipline (R22): ONE batched `gh` query per evaluation, 10s total
|
|
17
|
+
* budget; positives are persisted by the caller (monotone); negatives carry a
|
|
18
|
+
* 5-minute TTL. A network failure leaves artifacts uncorroborated (fail toward
|
|
19
|
+
* keep-working) with `degraded: true` named in the judge context.
|
|
20
|
+
*/
|
|
21
|
+
import type { AccretedArtifact } from './ScopeAccretionSweep.js';
|
|
22
|
+
export interface MergedPrFile {
|
|
23
|
+
path: string;
|
|
24
|
+
additions: number;
|
|
25
|
+
deletions: number;
|
|
26
|
+
}
|
|
27
|
+
export interface MergedPr {
|
|
28
|
+
number: number;
|
|
29
|
+
files: MergedPrFile[];
|
|
30
|
+
}
|
|
31
|
+
export interface CorroborationDeps {
|
|
32
|
+
/** Bounded `gh` runner — throws on failure/timeout. */
|
|
33
|
+
runGh: (args: string[], timeoutMs: number) => string;
|
|
34
|
+
/** SafeGitExecutor.readSync shape. */
|
|
35
|
+
readGit: (args: string[], cwd: string, timeoutMs?: number) => string;
|
|
36
|
+
fsExists: (p: string) => boolean;
|
|
37
|
+
/** Server-recorded ceremony evidence lookup (R32). */
|
|
38
|
+
conformanceInvocationsInWindow: (slug: string, startIso: string, endIso: string) => number;
|
|
39
|
+
now?: () => number;
|
|
40
|
+
/** Total gh budget in ms (default 10000, R22). */
|
|
41
|
+
ghBudgetMs?: number;
|
|
42
|
+
}
|
|
43
|
+
export interface CorroborationInput {
|
|
44
|
+
artifacts: AccretedArtifact[];
|
|
45
|
+
/** Paths already persisted as corroborated (monotone — skipped here). */
|
|
46
|
+
alreadyCorroborated: Record<string, unknown>;
|
|
47
|
+
/** Paths under a fresh negative-TTL — external queries skipped for these. */
|
|
48
|
+
negativeCached: Set<string>;
|
|
49
|
+
startedAt: string;
|
|
50
|
+
workDir: string;
|
|
51
|
+
}
|
|
52
|
+
export interface CorroborationResult {
|
|
53
|
+
/** Newly-cleared paths → evidence (the caller persists these, monotone). */
|
|
54
|
+
cleared: Record<string, {
|
|
55
|
+
by: string;
|
|
56
|
+
detail?: string;
|
|
57
|
+
}>;
|
|
58
|
+
/** Paths that were queried and NOT cleared (the caller stamps the 5-min TTL). */
|
|
59
|
+
newNegatives: string[];
|
|
60
|
+
/** gh/network failure — artifacts stay uncorroborated, named in judge context. */
|
|
61
|
+
degraded: boolean;
|
|
62
|
+
}
|
|
63
|
+
/** Spec slug from an artifact path (`docs/specs/foo-bar.md` → `foo-bar`). */
|
|
64
|
+
export declare function specSlugFromPath(relPath: string): string;
|
|
65
|
+
/**
|
|
66
|
+
* The merged-PR predicate, defined exactly (R33): the PR's merged diff includes
|
|
67
|
+
* the artifact's path AND ≥1 non-`docs/**` path with a combined non-docs diff
|
|
68
|
+
* of ≥10 changed lines. An artifact's own file NEVER corroborates itself; a
|
|
69
|
+
* docs-only PR NEVER corroborates a spec. `relaxOwnFile` covers the doc-whose-
|
|
70
|
+
* deliverable-IS-the-doc classes (audit/runbook/incident/script): the merged PR
|
|
71
|
+
* containing the file suffices.
|
|
72
|
+
*/
|
|
73
|
+
export declare function mergedPrSatisfiesPredicate(pr: MergedPr, artifactPath: string, relaxOwnFile: boolean): boolean;
|
|
74
|
+
export declare function resolveCorroboration(input: CorroborationInput, deps: CorroborationDeps): CorroborationResult;
|
|
75
|
+
export interface CorroborationInputWithShas extends CorroborationInput {
|
|
76
|
+
/** path.resolve(root) → start SHA, for the local-git shortcut. */
|
|
77
|
+
artifactStartShas: Record<string, string | null>;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=ScopeAccretionCorroboration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScopeAccretionCorroboration.d.ts","sourceRoot":"","sources":["../../src/core/ScopeAccretionCorroboration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,uDAAuD;IACvD,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;IACrD,sCAAsC;IACtC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACrE,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;IACjC,sDAAsD;IACtD,8BAA8B,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3F,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,yEAAyE;IACzE,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7C,6EAA6E;IAC7E,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,4EAA4E;IAC5E,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzD,iFAAiF;IACjF,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,kFAAkF;IAClF,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,OAAO,CAQ7G;AAwCD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,iBAAiB,GAAG,mBAAmB,CA2E5G;AAWD,MAAM,WAAW,0BAA2B,SAAQ,kBAAkB;IACpE,kEAAkE;IAClE,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;CAClD"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ScopeAccretionCorroboration — per-class deterministic "built/delivered"
|
|
3
|
+
* evidence, computed server-side at judge-fire time.
|
|
4
|
+
*
|
|
5
|
+
* Spec: docs/specs/autonomous-scope-accretion-completion.md §2.5
|
|
6
|
+
* (R21/R22/R32/R33/R34). An accreted deliverable clears ONLY by:
|
|
7
|
+
* - spec class: the convergence REPORT artifact + a server-recorded
|
|
8
|
+
* conformance-check invocation inside the run window (R32), OR a merged PR
|
|
9
|
+
* passing the exact predicate (R33);
|
|
10
|
+
* - audit/runbook/incident doc: a merged PR containing the file (own-file
|
|
11
|
+
* rule relaxed for a doc whose deliverable IS the doc);
|
|
12
|
+
* - script: a merged PR touching the script path;
|
|
13
|
+
* - the local-git POSITIVE-ONLY shortcut (R34): the path verifiably landed on
|
|
14
|
+
* `origin/main` after the start SHA — may CLEAR, never used to refuse.
|
|
15
|
+
*
|
|
16
|
+
* Cost discipline (R22): ONE batched `gh` query per evaluation, 10s total
|
|
17
|
+
* budget; positives are persisted by the caller (monotone); negatives carry a
|
|
18
|
+
* 5-minute TTL. A network failure leaves artifacts uncorroborated (fail toward
|
|
19
|
+
* keep-working) with `degraded: true` named in the judge context.
|
|
20
|
+
*/
|
|
21
|
+
import * as path from 'path';
|
|
22
|
+
/** Spec slug from an artifact path (`docs/specs/foo-bar.md` → `foo-bar`). */
|
|
23
|
+
export function specSlugFromPath(relPath) {
|
|
24
|
+
return path.basename(relPath).replace(/\.md$/, '');
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The merged-PR predicate, defined exactly (R33): the PR's merged diff includes
|
|
28
|
+
* the artifact's path AND ≥1 non-`docs/**` path with a combined non-docs diff
|
|
29
|
+
* of ≥10 changed lines. An artifact's own file NEVER corroborates itself; a
|
|
30
|
+
* docs-only PR NEVER corroborates a spec. `relaxOwnFile` covers the doc-whose-
|
|
31
|
+
* deliverable-IS-the-doc classes (audit/runbook/incident/script): the merged PR
|
|
32
|
+
* containing the file suffices.
|
|
33
|
+
*/
|
|
34
|
+
export function mergedPrSatisfiesPredicate(pr, artifactPath, relaxOwnFile) {
|
|
35
|
+
const containsArtifact = pr.files.some((f) => f.path === artifactPath);
|
|
36
|
+
if (!containsArtifact)
|
|
37
|
+
return false;
|
|
38
|
+
if (relaxOwnFile)
|
|
39
|
+
return true;
|
|
40
|
+
const nonDocs = pr.files.filter((f) => !f.path.startsWith('docs/') && f.path !== artifactPath);
|
|
41
|
+
if (nonDocs.length < 1)
|
|
42
|
+
return false;
|
|
43
|
+
const changedLines = nonDocs.reduce((sum, f) => sum + (f.additions || 0) + (f.deletions || 0), 0);
|
|
44
|
+
return changedLines >= 10;
|
|
45
|
+
}
|
|
46
|
+
function isSpecClass(relPath) {
|
|
47
|
+
return /^docs\/specs\/.+\.md$/.test(relPath) && !/\.eli16\.md$/.test(relPath);
|
|
48
|
+
}
|
|
49
|
+
function isRelaxedDocClass(relPath) {
|
|
50
|
+
return (/^docs\/audits\/.+\.md$/.test(relPath) ||
|
|
51
|
+
/^docs\/incidents\/.+\.md$/.test(relPath) ||
|
|
52
|
+
/(^|\/)[^/]*runbook[^/]*\.md$/i.test(relPath) ||
|
|
53
|
+
/^scripts\//.test(relPath));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Fetch merged PRs since the run start with ONE batched query (R22).
|
|
57
|
+
* `gh pr list --state merged --search "merged:><date>" --json number,files`.
|
|
58
|
+
*/
|
|
59
|
+
function fetchMergedPrs(deps, startedAt, budgetMs) {
|
|
60
|
+
try {
|
|
61
|
+
const day = (startedAt || '').slice(0, 10) || new Date().toISOString().slice(0, 10);
|
|
62
|
+
const raw = deps.runGh(['pr', 'list', '--state', 'merged', '--search', `merged:>=${day}`, '--json', 'number,files', '--limit', '50'], budgetMs);
|
|
63
|
+
const parsed = JSON.parse(raw);
|
|
64
|
+
if (!Array.isArray(parsed))
|
|
65
|
+
return null;
|
|
66
|
+
return parsed.map((p) => ({
|
|
67
|
+
number: p.number,
|
|
68
|
+
files: (p.files ?? []).map((f) => ({ path: f.path, additions: f.additions ?? 0, deletions: f.deletions ?? 0 })),
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
/* @silent-fallback-ok — a gh/network failure leaves artifacts uncorroborated
|
|
73
|
+
with `degraded: true` NAMED in the judge context (R22): fail toward
|
|
74
|
+
keep-working, never a wedge and never a false done. */
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export function resolveCorroboration(input, deps) {
|
|
79
|
+
const now = deps.now ?? (() => Date.now());
|
|
80
|
+
const t0 = now();
|
|
81
|
+
const ghBudget = deps.ghBudgetMs ?? 10_000;
|
|
82
|
+
const cleared = {};
|
|
83
|
+
const newNegatives = [];
|
|
84
|
+
let degraded = false;
|
|
85
|
+
const pending = input.artifacts.filter((a) => a.cls === 'deliverable' && !input.alreadyCorroborated[a.path]);
|
|
86
|
+
if (pending.length === 0)
|
|
87
|
+
return { cleared, newNegatives, degraded };
|
|
88
|
+
// Evidence-source separation (R34): gh is the merged-PR authority; local git
|
|
89
|
+
// is a POSITIVE-ONLY shortcut. Compute the cheap local arms first.
|
|
90
|
+
let mergedPrs = null;
|
|
91
|
+
let ghAttempted = false;
|
|
92
|
+
const nowIso = new Date(now()).toISOString();
|
|
93
|
+
for (const a of pending) {
|
|
94
|
+
// Arm (a) for the spec class: report + server-recorded ceremony evidence (R32).
|
|
95
|
+
if (isSpecClass(a.path)) {
|
|
96
|
+
const slug = specSlugFromPath(a.path);
|
|
97
|
+
const reportRel = `docs/specs/reports/${slug}-convergence.md`;
|
|
98
|
+
const reportExists = deps.fsExists(path.join(a.root, reportRel)) || deps.fsExists(path.join(input.workDir, reportRel));
|
|
99
|
+
if (reportExists && deps.conformanceInvocationsInWindow(slug, input.startedAt, nowIso) >= 1) {
|
|
100
|
+
cleared[a.path] = { by: 'ceremony-report', detail: reportRel };
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Local-git positive-only shortcut (R34): commits reachable from origin/main
|
|
105
|
+
// as last fetched — fetch staleness only DELAYS clearing (safe direction).
|
|
106
|
+
const base = findStartSha(input, a);
|
|
107
|
+
if (base) {
|
|
108
|
+
try {
|
|
109
|
+
const out = deps.readGit(['log', `${base}..origin/main`, '--oneline', '--', a.path], a.root, 4000);
|
|
110
|
+
if (out.trim().length > 0) {
|
|
111
|
+
cleared[a.path] = { by: 'local-git-origin-main' };
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
/* @silent-fallback-ok — R34: the local shortcut is positive-only; absence or
|
|
117
|
+
error falls through to the gh authority, never refuses. */
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Negative-TTL cache: skip the external query for fresh negatives (R22).
|
|
121
|
+
if (input.negativeCached.has(a.path))
|
|
122
|
+
continue;
|
|
123
|
+
// Merged-PR authority (gh) — ONE batched fetch per evaluation.
|
|
124
|
+
if (!ghAttempted) {
|
|
125
|
+
ghAttempted = true;
|
|
126
|
+
const left = ghBudget - (now() - t0);
|
|
127
|
+
if (left > 500) {
|
|
128
|
+
mergedPrs = fetchMergedPrs(deps, input.startedAt, Math.min(left, ghBudget));
|
|
129
|
+
if (mergedPrs === null)
|
|
130
|
+
degraded = true;
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
degraded = true;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (mergedPrs) {
|
|
137
|
+
const relax = isRelaxedDocClass(a.path);
|
|
138
|
+
const hit = mergedPrs.find((pr) => mergedPrSatisfiesPredicate(pr, a.path, relax));
|
|
139
|
+
if (hit) {
|
|
140
|
+
cleared[a.path] = { by: 'merged-pr', detail: `#${hit.number}` };
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
newNegatives.push(a.path);
|
|
144
|
+
}
|
|
145
|
+
// gh degraded → leave uncorroborated with NO negative stamp (a network
|
|
146
|
+
// failure must not suppress the retry once gh recovers).
|
|
147
|
+
}
|
|
148
|
+
return { cleared, newNegatives, degraded };
|
|
149
|
+
}
|
|
150
|
+
function findStartSha(input, a) {
|
|
151
|
+
// The caller's record carries per-root SHAs; the sweep artifact only carries
|
|
152
|
+
// its root. We accept an injected resolution via input — for simplicity the
|
|
153
|
+
// route passes base-root SHAs through `artifactStartShas`.
|
|
154
|
+
const shas = input.artifactStartShas;
|
|
155
|
+
if (!shas)
|
|
156
|
+
return null;
|
|
157
|
+
return shas[path.resolve(a.root)] ?? null;
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=ScopeAccretionCorroboration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScopeAccretionCorroboration.js","sourceRoot":"","sources":["../../src/core/ScopeAccretionCorroboration.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ScopeAccretionRatifier — the conversational ratification path
|
|
3
|
+
* (proposal → server-authored enumeration → confirmation), consumed ONLY at
|
|
4
|
+
* the server's live Telegram receive path (R45).
|
|
5
|
+
*
|
|
6
|
+
* Spec: docs/specs/autonomous-scope-accretion-completion.md §2.6
|
|
7
|
+
* (R23/R37/R38/R45). Both the defer-vocabulary trigger detection AND the
|
|
8
|
+
* confirmation matching run as each inbound topic message passes through the
|
|
9
|
+
* server's own Telegram receive handling — the on-disk history JSONL is NOT
|
|
10
|
+
* part of the mechanism (a message the server did not itself receive from
|
|
11
|
+
* Telegram can never trigger or confirm). Matched events persist as
|
|
12
|
+
* server-owned records in the run record.
|
|
13
|
+
*
|
|
14
|
+
* Display integrity (Agent Proposes, Operator Approves): the operator approves
|
|
15
|
+
* a SERVER-authored statement whose displayed set is byte-identical to what
|
|
16
|
+
* executes — the enumeration is composed here, sent under the server's own bot
|
|
17
|
+
* credentials, and its message id recorded; a confirmation binds exactly the
|
|
18
|
+
* enumerated set via the message-id chain.
|
|
19
|
+
*/
|
|
20
|
+
import type { AutonomousRunStore, AutonomousRunRecord } from './AutonomousRunStore.js';
|
|
21
|
+
export interface InboundReceiveEvent {
|
|
22
|
+
topicId: number;
|
|
23
|
+
text: string;
|
|
24
|
+
/** The AUTHENTICATED platform sender id (Know Your Principal). */
|
|
25
|
+
senderUid: string;
|
|
26
|
+
messageId: number;
|
|
27
|
+
replyToMessageId?: number;
|
|
28
|
+
/** Message date (ms epoch). */
|
|
29
|
+
at: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Parse a RAW Telegram receive-path message object (the `update.message` /
|
|
33
|
+
* Bot-API `result` shape, as JSON text) into the InboundReceiveEvent fields
|
|
34
|
+
* the ratification matchers consume. Registered parser (Scrape/Parser Fixture
|
|
35
|
+
* Realness) — fed byte-for-byte captured REAL Telegram message objects in
|
|
36
|
+
* tests/fixtures/captured/scope-accretion-telegram-receive/. Returns null on
|
|
37
|
+
* anything that is not a well-formed text message object.
|
|
38
|
+
*/
|
|
39
|
+
export declare function parseReceivePathMessage(rawJson: string): InboundReceiveEvent | null;
|
|
40
|
+
/**
|
|
41
|
+
* Deterministic defer-intent trigger match (registered parser — fed captured
|
|
42
|
+
* Telegram receive-path payloads in tests/fixtures/captured/). Returns the
|
|
43
|
+
* matched phrase or null.
|
|
44
|
+
*/
|
|
45
|
+
export declare function parseDeferTrigger(text: string): string | null;
|
|
46
|
+
export interface ConfirmationMatch {
|
|
47
|
+
/** The enumeration the confirmation binds (message-id chain), or null. */
|
|
48
|
+
boundSetHash: string | null;
|
|
49
|
+
affirmative: boolean;
|
|
50
|
+
replyAnchored: boolean;
|
|
51
|
+
ratifyToken: boolean;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Confirmation matching (R38 — strict, the one path that pushes toward exit):
|
|
55
|
+
* ONLY a verified-operator message that is reply-anchored to the recorded
|
|
56
|
+
* enumeration message OR contains the explicit token "ratify", with
|
|
57
|
+
* affirmative content, binds — and it binds exactly the enumerated set. A bare
|
|
58
|
+
* affirmative NOT reply-anchored resolves to the EMPTY set. (Registered
|
|
59
|
+
* parser — captured receive-path payloads incl. reply_to_message shapes.)
|
|
60
|
+
*/
|
|
61
|
+
export declare function parseRatificationConfirmation(evtOrRaw: {
|
|
62
|
+
text: string;
|
|
63
|
+
replyToMessageId?: number;
|
|
64
|
+
} | string, enumerations: Array<{
|
|
65
|
+
setHash: string;
|
|
66
|
+
messageId: number;
|
|
67
|
+
}>): ConfirmationMatch;
|
|
68
|
+
export interface RatifierDeps {
|
|
69
|
+
store: AutonomousRunStore;
|
|
70
|
+
/** Verified operator uid for a topic (TopicOperatorStore) — null = unbound. */
|
|
71
|
+
getOperatorUid: (topicId: number) => string | null;
|
|
72
|
+
/** Server-credentialed send (TelegramAdapter.sendToTopic shape, R37). */
|
|
73
|
+
sendToTopic: (topicId: number, text: string) => Promise<{
|
|
74
|
+
messageId: number;
|
|
75
|
+
}>;
|
|
76
|
+
/** Dashboard deep link to the PIN-gated ratify surface (one-tap path). */
|
|
77
|
+
dashboardLink?: (topicId: string) => string | null;
|
|
78
|
+
recordMetric?: (outcome: 'fired' | 'noop') => void;
|
|
79
|
+
log?: (msg: string) => void;
|
|
80
|
+
}
|
|
81
|
+
export declare class ScopeAccretionRatifier {
|
|
82
|
+
private readonly deps;
|
|
83
|
+
constructor(deps: RatifierDeps);
|
|
84
|
+
/**
|
|
85
|
+
* Observe one inbound topic message from the LIVE receive path. Signal-only
|
|
86
|
+
* for message delivery: never blocks, never rewrites — errors are swallowed
|
|
87
|
+
* after logging (the receive path must never fail because of this observer).
|
|
88
|
+
*/
|
|
89
|
+
observeInbound(evt: InboundReceiveEvent): Promise<void>;
|
|
90
|
+
private observeInboundInner;
|
|
91
|
+
}
|
|
92
|
+
export type { AutonomousRunRecord };
|
|
93
|
+
//# sourceMappingURL=ScopeAccretionRatifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScopeAccretionRatifier.d.ts","sourceRoot":"","sources":["../../src/core/ScopeAccretionRatifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAmBvF,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+BAA+B;IAC/B,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAyBnF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM7D;AAED,MAAM,WAAW,iBAAiB;IAChC,0EAA0E;IAC1E,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,EAC9D,YAAY,EAAE,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,GAC1D,iBAAiB,CA6BnB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,+EAA+E;IAC/E,cAAc,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACnD,yEAAyE;IACzE,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/E,0EAA0E;IAC1E,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACnD,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;IACnD,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,qBAAa,sBAAsB;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,YAAY;IAE/C;;;;OAIG;IACG,cAAc,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;YAQ/C,mBAAmB;CA6FlC;AAED,YAAY,EAAE,mBAAmB,EAAE,CAAC"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ScopeAccretionRatifier — the conversational ratification path
|
|
3
|
+
* (proposal → server-authored enumeration → confirmation), consumed ONLY at
|
|
4
|
+
* the server's live Telegram receive path (R45).
|
|
5
|
+
*
|
|
6
|
+
* Spec: docs/specs/autonomous-scope-accretion-completion.md §2.6
|
|
7
|
+
* (R23/R37/R38/R45). Both the defer-vocabulary trigger detection AND the
|
|
8
|
+
* confirmation matching run as each inbound topic message passes through the
|
|
9
|
+
* server's own Telegram receive handling — the on-disk history JSONL is NOT
|
|
10
|
+
* part of the mechanism (a message the server did not itself receive from
|
|
11
|
+
* Telegram can never trigger or confirm). Matched events persist as
|
|
12
|
+
* server-owned records in the run record.
|
|
13
|
+
*
|
|
14
|
+
* Display integrity (Agent Proposes, Operator Approves): the operator approves
|
|
15
|
+
* a SERVER-authored statement whose displayed set is byte-identical to what
|
|
16
|
+
* executes — the enumeration is composed here, sent under the server's own bot
|
|
17
|
+
* credentials, and its message id recorded; a confirmation binds exactly the
|
|
18
|
+
* enumerated set via the message-id chain.
|
|
19
|
+
*/
|
|
20
|
+
import { createHash } from 'crypto';
|
|
21
|
+
import { hashPathSet } from './AutonomousRunStore.js';
|
|
22
|
+
/** Frontloaded defer-intent vocabulary (§2.6 trigger list). */
|
|
23
|
+
const DEFER_VOCABULARY = [
|
|
24
|
+
'defer',
|
|
25
|
+
'later session',
|
|
26
|
+
"don't build",
|
|
27
|
+
'dont build',
|
|
28
|
+
'skip building',
|
|
29
|
+
'leave for a future',
|
|
30
|
+
'ratify deferral',
|
|
31
|
+
];
|
|
32
|
+
const AFFIRMATIVES = ['yes', 'approve', 'confirm', 'approved', 'confirmed', '\u{1F44D}'];
|
|
33
|
+
/** Enumeration clamp (§2.6): 50 paths + "and N more". */
|
|
34
|
+
const ENUMERATION_CLAMP = 50;
|
|
35
|
+
/**
|
|
36
|
+
* Parse a RAW Telegram receive-path message object (the `update.message` /
|
|
37
|
+
* Bot-API `result` shape, as JSON text) into the InboundReceiveEvent fields
|
|
38
|
+
* the ratification matchers consume. Registered parser (Scrape/Parser Fixture
|
|
39
|
+
* Realness) — fed byte-for-byte captured REAL Telegram message objects in
|
|
40
|
+
* tests/fixtures/captured/scope-accretion-telegram-receive/. Returns null on
|
|
41
|
+
* anything that is not a well-formed text message object.
|
|
42
|
+
*/
|
|
43
|
+
export function parseReceivePathMessage(rawJson) {
|
|
44
|
+
let msg;
|
|
45
|
+
try {
|
|
46
|
+
msg = JSON.parse(rawJson);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
/* @silent-fallback-ok — a malformed receive-path payload matches NOTHING:
|
|
50
|
+
fail-closed for ratification (the one path that pushes toward exit). */
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
if (!msg || typeof msg !== 'object')
|
|
54
|
+
return null;
|
|
55
|
+
const text = typeof msg.text === 'string' ? msg.text : '';
|
|
56
|
+
const messageId = typeof msg.message_id === 'number' ? msg.message_id : NaN;
|
|
57
|
+
if (!text || !Number.isFinite(messageId))
|
|
58
|
+
return null;
|
|
59
|
+
const from = (msg.from ?? {});
|
|
60
|
+
const reply = (msg.reply_to_message ?? null);
|
|
61
|
+
const threadId = typeof msg.message_thread_id === 'number' ? msg.message_thread_id : 1;
|
|
62
|
+
const date = typeof msg.date === 'number' ? msg.date * 1000 : Date.now();
|
|
63
|
+
return {
|
|
64
|
+
topicId: threadId,
|
|
65
|
+
text,
|
|
66
|
+
senderUid: from && typeof from.id === 'number' ? String(from.id) : '',
|
|
67
|
+
messageId,
|
|
68
|
+
replyToMessageId: reply && typeof reply.message_id === 'number' ? reply.message_id : undefined,
|
|
69
|
+
at: date,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Deterministic defer-intent trigger match (registered parser — fed captured
|
|
74
|
+
* Telegram receive-path payloads in tests/fixtures/captured/). Returns the
|
|
75
|
+
* matched phrase or null.
|
|
76
|
+
*/
|
|
77
|
+
export function parseDeferTrigger(text) {
|
|
78
|
+
const lc = (text || '').toLowerCase();
|
|
79
|
+
for (const phrase of DEFER_VOCABULARY) {
|
|
80
|
+
if (lc.includes(phrase))
|
|
81
|
+
return phrase;
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Confirmation matching (R38 — strict, the one path that pushes toward exit):
|
|
87
|
+
* ONLY a verified-operator message that is reply-anchored to the recorded
|
|
88
|
+
* enumeration message OR contains the explicit token "ratify", with
|
|
89
|
+
* affirmative content, binds — and it binds exactly the enumerated set. A bare
|
|
90
|
+
* affirmative NOT reply-anchored resolves to the EMPTY set. (Registered
|
|
91
|
+
* parser — captured receive-path payloads incl. reply_to_message shapes.)
|
|
92
|
+
*/
|
|
93
|
+
export function parseRatificationConfirmation(evtOrRaw, enumerations) {
|
|
94
|
+
// Accept a RAW receive-path message object (JSON text) directly — the
|
|
95
|
+
// captured-fixture tests feed the real bytes; live callers pass the
|
|
96
|
+
// already-derived event. An unparseable raw payload matches nothing.
|
|
97
|
+
const evt = typeof evtOrRaw === 'string'
|
|
98
|
+
? (parseReceivePathMessage(evtOrRaw) ?? { text: '', replyToMessageId: undefined })
|
|
99
|
+
: evtOrRaw;
|
|
100
|
+
const lc = (evt.text || '').toLowerCase().trim();
|
|
101
|
+
const affirmative = AFFIRMATIVES.some((a) => lc === a || lc.startsWith(`${a} `) || lc.includes(` ${a}`) || lc.includes(a === '\u{1F44D}' ? a : `${a}.`) || lc === `${a}!`);
|
|
102
|
+
const ratifyToken = /\bratify\b/.test(lc);
|
|
103
|
+
let anchored;
|
|
104
|
+
if (typeof evt.replyToMessageId === 'number') {
|
|
105
|
+
anchored = enumerations.find((e) => e.messageId === evt.replyToMessageId);
|
|
106
|
+
}
|
|
107
|
+
const replyAnchored = !!anchored;
|
|
108
|
+
if (!affirmative && !ratifyToken) {
|
|
109
|
+
return { boundSetHash: null, affirmative, replyAnchored, ratifyToken };
|
|
110
|
+
}
|
|
111
|
+
if (anchored && (affirmative || ratifyToken)) {
|
|
112
|
+
return { boundSetHash: anchored.setHash, affirmative, replyAnchored, ratifyToken };
|
|
113
|
+
}
|
|
114
|
+
if (ratifyToken && affirmative && enumerations.length > 0) {
|
|
115
|
+
// Explicit "ratify" token without a reply anchor binds the most recent
|
|
116
|
+
// recorded enumeration (§2.6: "or a message containing the explicit token
|
|
117
|
+
// 'ratify'"). Still bound by the message-id chain: the LAST enumeration.
|
|
118
|
+
return { boundSetHash: enumerations[enumerations.length - 1].setHash, affirmative, replyAnchored, ratifyToken };
|
|
119
|
+
}
|
|
120
|
+
// A bare affirmative NOT reply-anchored resolves to the EMPTY set (R38).
|
|
121
|
+
return { boundSetHash: null, affirmative, replyAnchored, ratifyToken };
|
|
122
|
+
}
|
|
123
|
+
export class ScopeAccretionRatifier {
|
|
124
|
+
deps;
|
|
125
|
+
constructor(deps) {
|
|
126
|
+
this.deps = deps;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Observe one inbound topic message from the LIVE receive path. Signal-only
|
|
130
|
+
* for message delivery: never blocks, never rewrites — errors are swallowed
|
|
131
|
+
* after logging (the receive path must never fail because of this observer).
|
|
132
|
+
*/
|
|
133
|
+
async observeInbound(evt) {
|
|
134
|
+
try {
|
|
135
|
+
await this.observeInboundInner(evt);
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
this.deps.log?.(`[scope-accretion] ratifier observe error (ignored): ${err instanceof Error ? err.message : String(err)}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
async observeInboundInner(evt) {
|
|
142
|
+
const topicId = String(evt.topicId);
|
|
143
|
+
const rec = this.deps.store.getRecord(topicId);
|
|
144
|
+
if (!rec || !this.deps.store.isActive(rec, evt.at))
|
|
145
|
+
return;
|
|
146
|
+
// Know Your Principal: only the VERIFIED operator of this topic participates
|
|
147
|
+
// (TopicOperatorStore uid match on the authenticated sender id).
|
|
148
|
+
const operatorUid = this.deps.getOperatorUid(evt.topicId);
|
|
149
|
+
if (!operatorUid || operatorUid !== String(evt.senderUid))
|
|
150
|
+
return;
|
|
151
|
+
// 1) Confirmation matching FIRST (an affirmative reply must not be re-read
|
|
152
|
+
// as a fresh trigger).
|
|
153
|
+
const match = parseRatificationConfirmation({ text: evt.text, replyToMessageId: evt.replyToMessageId }, rec.enumerations.map((e) => ({ setHash: e.setHash, messageId: e.messageId })));
|
|
154
|
+
if (match.boundSetHash) {
|
|
155
|
+
const enumRec = rec.enumerations.find((e) => e.setHash === match.boundSetHash);
|
|
156
|
+
if (enumRec && enumRec.artifacts.length > 0) {
|
|
157
|
+
this.deps.store.update(topicId, rec.runId, (r) => {
|
|
158
|
+
for (const p of enumRec.artifacts) {
|
|
159
|
+
if (!r.ratifiedArtifacts.includes(p))
|
|
160
|
+
r.ratifiedArtifacts.push(p);
|
|
161
|
+
}
|
|
162
|
+
r.ratifications.push({
|
|
163
|
+
via: 'conversation',
|
|
164
|
+
at: new Date(evt.at).toISOString(),
|
|
165
|
+
artifacts: [...enumRec.artifacts],
|
|
166
|
+
enumerationMessageId: enumRec.messageId,
|
|
167
|
+
confirmationMessageId: evt.messageId,
|
|
168
|
+
verifiedOperatorUidHash: createHash('sha256').update(String(evt.senderUid)).digest('hex'),
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
this.deps.recordMetric?.('fired');
|
|
172
|
+
await this.deps.sendToTopic(evt.topicId, `Deferral ratified for ${enumRec.artifacts.length} artifact${enumRec.artifacts.length === 1 ? '' : 's'} — the completion gate no longer holds on them.`).catch(() => { });
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (match.affirmative && !match.replyAnchored && !match.ratifyToken) {
|
|
177
|
+
// R38: a busy topic's unrelated "yes" ratifies NOTHING — resolved to the
|
|
178
|
+
// empty set, no record, no send.
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
// 2) Trigger detection — defer-intent vocabulary within the window
|
|
182
|
+
// [max(started_at, oldest unbuilt artifact ts), now] (§2.6).
|
|
183
|
+
const phrase = parseDeferTrigger(evt.text);
|
|
184
|
+
if (!phrase)
|
|
185
|
+
return;
|
|
186
|
+
const unbuilt = rec.lastUnbuilt ?? [];
|
|
187
|
+
if (unbuilt.length === 0) {
|
|
188
|
+
// A pre-accretion blanket "defer those" alone ratifies NOTHING; with no
|
|
189
|
+
// computed unbuilt set there is nothing to enumerate.
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const oldestUnbuiltTs = unbuilt.reduce((min, u) => Math.min(min, Date.parse(u.firstSeenAt) || Infinity), Infinity);
|
|
193
|
+
const windowStart = Math.max(Date.parse(rec.startedAt) || 0, Number.isFinite(oldestUnbuiltTs) ? oldestUnbuiltTs : 0);
|
|
194
|
+
if (evt.at < windowStart)
|
|
195
|
+
return;
|
|
196
|
+
// Persist the trigger record (server-owned, never re-read from any file).
|
|
197
|
+
this.deps.store.update(topicId, rec.runId, (r) => {
|
|
198
|
+
r.triggers.push({ at: new Date(evt.at).toISOString(), messageId: evt.messageId, phrase });
|
|
199
|
+
if (r.triggers.length > 50)
|
|
200
|
+
r.triggers = r.triggers.slice(-50);
|
|
201
|
+
});
|
|
202
|
+
// Server-authored enumeration (R37), deduped per unbuilt-set hash — an
|
|
203
|
+
// unchanged set re-uses the recorded enumeration and never re-sends.
|
|
204
|
+
const paths = unbuilt.map((u) => u.path);
|
|
205
|
+
const setHash = hashPathSet(paths);
|
|
206
|
+
if (rec.enumerations.some((e) => e.setHash === setHash))
|
|
207
|
+
return;
|
|
208
|
+
const shown = paths.slice(0, ENUMERATION_CLAMP);
|
|
209
|
+
const more = paths.length - shown.length;
|
|
210
|
+
const link = this.deps.dashboardLink?.(topicId);
|
|
211
|
+
const lines = [
|
|
212
|
+
`Ratify deferring these ${paths.length} artifact${paths.length === 1 ? '' : 's'}?`,
|
|
213
|
+
...shown.map((p) => `- ${p}`),
|
|
214
|
+
...(more > 0 ? [`…and ${more} more`] : []),
|
|
215
|
+
'',
|
|
216
|
+
'Reply to THIS message with yes/approve, or use the dashboard.',
|
|
217
|
+
...(link ? [link] : []),
|
|
218
|
+
];
|
|
219
|
+
const sent = await this.deps.sendToTopic(evt.topicId, lines.join('\n'));
|
|
220
|
+
this.deps.store.update(topicId, rec.runId, (r) => {
|
|
221
|
+
r.enumerations.push({ setHash, messageId: sent.messageId, at: new Date().toISOString(), artifacts: paths });
|
|
222
|
+
if (r.enumerations.length > 20)
|
|
223
|
+
r.enumerations = r.enumerations.slice(-20);
|
|
224
|
+
});
|
|
225
|
+
this.deps.recordMetric?.('fired');
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=ScopeAccretionRatifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScopeAccretionRatifier.js","sourceRoot":"","sources":["../../src/core/ScopeAccretionRatifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,+DAA+D;AAC/D,MAAM,gBAAgB,GAAG;IACvB,OAAO;IACP,eAAe;IACf,aAAa;IACb,YAAY;IACZ,eAAe;IACf,oBAAoB;IACpB,iBAAiB;CACT,CAAC;AAEX,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,CAAU,CAAC;AAElG,yDAAyD;AACzD,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAa7B;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAe;IACrD,IAAI,GAA4B,CAAC;IACjC,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAA4B,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP;kFAC0E;QAC1E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACjD,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1D,MAAM,SAAS,GAAG,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC;IAC5E,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IACtD,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAA4B,CAAC;IACzD,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,gBAAgB,IAAI,IAAI,CAAmC,CAAC;IAC/E,MAAM,QAAQ,GAAG,OAAO,GAAG,CAAC,iBAAiB,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;IACvF,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;IACzE,OAAO;QACL,OAAO,EAAE,QAAQ;QACjB,IAAI;QACJ,SAAS,EAAE,IAAI,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;QACrE,SAAS;QACT,gBAAgB,EAAE,KAAK,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;QAC9F,EAAE,EAAE,IAAI;KACT,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,MAAM,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IACtC,KAAK,MAAM,MAAM,IAAI,gBAAgB,EAAE,CAAC;QACtC,IAAI,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,OAAO,MAAM,CAAC;IACzC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAUD;;;;;;;GAOG;AACH,MAAM,UAAU,6BAA6B,CAC3C,QAA8D,EAC9D,YAA2D;IAE3D,sEAAsE;IACtE,oEAAoE;IACpE,qEAAqE;IACrE,MAAM,GAAG,GAAG,OAAO,QAAQ,KAAK,QAAQ;QACtC,CAAC,CAAC,CAAC,uBAAuB,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,gBAAgB,EAAE,SAAS,EAAE,CAAC;QAClF,CAAC,CAAC,QAAQ,CAAC;IACb,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IACjD,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3K,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1C,IAAI,QAA4D,CAAC;IACjE,IAAI,OAAO,GAAG,CAAC,gBAAgB,KAAK,QAAQ,EAAE,CAAC;QAC7C,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC5E,CAAC;IACD,MAAM,aAAa,GAAG,CAAC,CAAC,QAAQ,CAAC;IACjC,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,EAAE,CAAC;QACjC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC;IACzE,CAAC;IACD,IAAI,QAAQ,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,EAAE,CAAC;QAC7C,OAAO,EAAE,YAAY,EAAE,QAAQ,CAAC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC;IACrF,CAAC;IACD,IAAI,WAAW,IAAI,WAAW,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1D,uEAAuE;QACvE,0EAA0E;QAC1E,yEAAyE;QACzE,OAAO,EAAE,YAAY,EAAE,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC;IAClH,CAAC;IACD,yEAAyE;IACzE,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC;AACzE,CAAC;AAcD,MAAM,OAAO,sBAAsB;IACJ;IAA7B,YAA6B,IAAkB;QAAlB,SAAI,GAAJ,IAAI,CAAc;IAAG,CAAC;IAEnD;;;;OAIG;IACH,KAAK,CAAC,cAAc,CAAC,GAAwB;QAC3C,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,uDAAuD,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7H,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,mBAAmB,CAAC,GAAwB;QACxD,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC/C,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;YAAE,OAAO;QAE3D,6EAA6E;QAC7E,iEAAiE;QACjE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC1D,IAAI,CAAC,WAAW,IAAI,WAAW,KAAK,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;YAAE,OAAO;QAElE,2EAA2E;QAC3E,0BAA0B;QAC1B,MAAM,KAAK,GAAG,6BAA6B,CACzC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,CAAC,gBAAgB,EAAE,EAC1D,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAC9E,CAAC;QACF,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,CAAC,YAAY,CAAC,CAAC;YAC/E,IAAI,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC5C,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE;oBAC/C,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;wBAClC,IAAI,CAAC,CAAC,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC;4BAAE,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBACpE,CAAC;oBACD,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC;wBACnB,GAAG,EAAE,cAAc;wBACnB,EAAE,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE;wBAClC,SAAS,EAAE,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC;wBACjC,oBAAoB,EAAE,OAAO,CAAC,SAAS;wBACvC,qBAAqB,EAAE,GAAG,CAAC,SAAS;wBACpC,uBAAuB,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;qBAC1F,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;gBACH,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,OAAO,CAAC,CAAC;gBAClC,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,CACzB,GAAG,CAAC,OAAO,EACX,yBAAyB,OAAO,CAAC,SAAS,CAAC,MAAM,YAAY,OAAO,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,iDAAiD,CACxJ,CAAC,KAAK,CAAC,GAAG,EAAE,GAAyB,CAAC,CAAC,CAAC;gBACzC,OAAO;YACT,CAAC;QACH,CAAC;QACD,IAAI,KAAK,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACpE,yEAAyE;YACzE,iCAAiC;YACjC,OAAO;QACT,CAAC;QAED,mEAAmE;QACnE,gEAAgE;QAChE,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;QACtC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,wEAAwE;YACxE,sDAAsD;YACtD,OAAO;QACT,CAAC;QACD,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CACpC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,QAAQ,CAAC,EAChE,QAAQ,CACT,CAAC;QACF,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrH,IAAI,GAAG,CAAC,EAAE,GAAG,WAAW;YAAE,OAAO;QAEjC,0EAA0E;QAC1E,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE;YAC/C,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;YAC1F,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,EAAE;gBAAE,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QAEH,uEAAuE;QACvE,qEAAqE;QACrE,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC;YAAE,OAAO;QAEhE,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QACzC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG;YACZ,0BAA0B,KAAK,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG;YAClF,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7B,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1C,EAAE;YACF,+DAA+D;YAC/D,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SACxB,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACxE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE;YAC/C,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;YAC5G,IAAI,CAAC,CAAC,YAAY,CAAC,MAAM,GAAG,EAAE;gBAAE,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAC7E,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;CACF"}
|