agent-afk 5.341.0 → 5.342.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/dist/agent/episodes/extract.d.ts +2 -0
- package/dist/agent/episodes/index.d.ts +6 -0
- package/dist/agent/episodes/session-end-hook.d.ts +2 -0
- package/dist/agent/episodes/synthesize.d.ts +2 -0
- package/dist/agent/episodes/types.d.ts +24 -0
- package/dist/agent/episodes/writer.d.ts +4 -0
- package/dist/agent/provider.d.ts +0 -5
- package/dist/agent/providers/anthropic-direct/query/cwd-dependents.d.ts +1 -0
- package/dist/agent/providers/anthropic-direct/query-runtime.d.ts +0 -5
- package/dist/agent/providers/openai-compatible/index.d.ts +2 -1
- package/dist/agent/providers/openai-compatible/index.options.d.ts +1 -0
- package/dist/agent/providers/openai-compatible/provider-schemas.d.ts +3 -0
- package/dist/agent/providers/router/provider-router.d.ts +0 -5
- package/dist/agent/session/agent-session.d.ts +0 -5
- package/dist/agent/session/ledger-lifecycle.d.ts +6 -0
- package/dist/agent/session/session-config.d.ts +0 -5
- package/dist/agent/session/session-meta.d.ts +8 -0
- package/dist/bundled-plugins/awa-bundled/skills/consumer-map/SKILL.md +154 -0
- package/dist/bundled-plugins/awa-bundled/skills/devils-advocate/SKILL.md +12 -0
- package/dist/bundled-plugins/awa-bundled/skills/ground-state/SKILL.md +8 -11
- package/dist/cli/commands/episode.d.ts +2 -0
- package/dist/cli.mjs +455 -428
- package/dist/config/env.d.ts +8 -0
- package/dist/config/env.episode.d.ts +9 -0
- package/dist/index.mjs +366 -366
- package/dist/telegram.mjs +403 -383
- package/package.json +1 -1
- package/dist/cli/slash/commands/reauth.d.ts +0 -2
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type { EpisodeRecord, EpisodeInput } from './types.js';
|
|
2
|
+
export { extractEpisodeInput } from './extract.js';
|
|
3
|
+
export { synthesizeEpisode } from './synthesize.js';
|
|
4
|
+
export { writeEpisode, formatEpisodeContent, sanitizeNarrative } from './writer.js';
|
|
5
|
+
import type { EpisodeRecord } from './types.js';
|
|
6
|
+
export declare function synthesizeAndWriteEpisode(sessionId: string): Promise<EpisodeRecord>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface EpisodeRecord {
|
|
2
|
+
sessionId: string;
|
|
3
|
+
goal: string;
|
|
4
|
+
approach: string;
|
|
5
|
+
pivots: string[];
|
|
6
|
+
decisions: string[];
|
|
7
|
+
outcome: string;
|
|
8
|
+
openQuestions: string[];
|
|
9
|
+
filesKey: string[];
|
|
10
|
+
tags: string[];
|
|
11
|
+
narrative: string;
|
|
12
|
+
synthesizedAt: string;
|
|
13
|
+
}
|
|
14
|
+
export interface EpisodeInput {
|
|
15
|
+
sessionId: string;
|
|
16
|
+
firstUserMessage: string;
|
|
17
|
+
markSequence: string[];
|
|
18
|
+
toolsUsed: string[];
|
|
19
|
+
toolErrors: string[];
|
|
20
|
+
lastAssistantMessage: string;
|
|
21
|
+
facetSummary?: string;
|
|
22
|
+
durationMs?: number;
|
|
23
|
+
costUsd?: number;
|
|
24
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { EpisodeRecord } from './types.js';
|
|
2
|
+
export declare function sanitizeNarrative(text: string): string;
|
|
3
|
+
export declare function formatEpisodeContent(episode: EpisodeRecord): string;
|
|
4
|
+
export declare function writeEpisode(episode: EpisodeRecord, memoryDir?: string): Promise<void>;
|
package/dist/agent/provider.d.ts
CHANGED
|
@@ -194,11 +194,6 @@ export interface ProviderQuery extends AsyncIterable<ProviderEvent> {
|
|
|
194
194
|
setBeforeTurnEnd?(cb: ((continuation: number, assistantText?: string) => Promise<{
|
|
195
195
|
continueWith?: string;
|
|
196
196
|
} | undefined>) | undefined): void;
|
|
197
|
-
reauth?(): Promise<{
|
|
198
|
-
accountId: string;
|
|
199
|
-
oldAccountId: string;
|
|
200
|
-
swapped: boolean;
|
|
201
|
-
} | null>;
|
|
202
197
|
close(): void | Promise<void>;
|
|
203
198
|
}
|
|
204
199
|
export interface ProviderCommandInfo {
|
|
@@ -12,6 +12,7 @@ export type CwdDependentsFactory = (newCwd: string) => {
|
|
|
12
12
|
export interface CwdDependentsFactoryArgs {
|
|
13
13
|
stableSystemPrefix: StableSystemParts;
|
|
14
14
|
config: AgentConfig;
|
|
15
|
+
resolvedSessionId: string | undefined;
|
|
15
16
|
surface: string;
|
|
16
17
|
runtimeStateSource: RuntimeStateSource;
|
|
17
18
|
getCurrentCwd: () => string | undefined;
|
|
@@ -57,11 +57,6 @@ export declare class AnthropicDirectQuery implements ProviderQuery {
|
|
|
57
57
|
getContextUsage(): Promise<ProviderContextUsage>;
|
|
58
58
|
mcpServerStatus(): Promise<ProviderMcpServerStatus[]>;
|
|
59
59
|
accountInfo(): Promise<ProviderAccountInfo>;
|
|
60
|
-
reauth(): Promise<{
|
|
61
|
-
accountId: string;
|
|
62
|
-
oldAccountId: string;
|
|
63
|
-
swapped: boolean;
|
|
64
|
-
} | null>;
|
|
65
60
|
rewindFiles(userMessageId: string, options?: {
|
|
66
61
|
dryRun?: boolean;
|
|
67
62
|
}): Promise<ProviderRewindResult>;
|
|
@@ -9,7 +9,7 @@ export declare class OpenAICompatibleProvider implements ModelProvider {
|
|
|
9
9
|
private _stateStore;
|
|
10
10
|
private readonly _injectedMemoryStore;
|
|
11
11
|
private readonly _injectedStateStore;
|
|
12
|
-
private
|
|
12
|
+
private schemas;
|
|
13
13
|
private _defaultHeaders;
|
|
14
14
|
private _sharedReadRoots;
|
|
15
15
|
private _sharedWriteRoots;
|
|
@@ -23,6 +23,7 @@ export declare class OpenAICompatibleProvider implements ModelProvider {
|
|
|
23
23
|
baseURL?: string;
|
|
24
24
|
defaultHeaders?: Record<string, string>;
|
|
25
25
|
}): void;
|
|
26
|
+
setSubscribeHandler(handler: import('../../tools/types.js').ToolHandler): void;
|
|
26
27
|
query(args: ProviderQueryArgs): ProviderQuery;
|
|
27
28
|
private buildDispatcher;
|
|
28
29
|
private ensureSharedRoots;
|
|
@@ -20,6 +20,7 @@ export interface OpenAICompatibleProviderOptions extends ChildSessionOptions {
|
|
|
20
20
|
composeExecutor?: ComposeExecutor;
|
|
21
21
|
memoryStore?: MemoryStore;
|
|
22
22
|
workspaceStore?: WorkspaceStore;
|
|
23
|
+
subscribeHandler?: import('../../tools/types.js').ToolHandler;
|
|
23
24
|
stateStore?: StateStore;
|
|
24
25
|
surface?: string;
|
|
25
26
|
readOnlyMemory?: boolean;
|
|
@@ -46,11 +46,6 @@ export declare class ProviderRouter implements ProviderQuery {
|
|
|
46
46
|
setPermissionMode(mode: string): Promise<void>;
|
|
47
47
|
setCwd(cwd: string): void;
|
|
48
48
|
setSystemPrompt(basePrompt: string | undefined): boolean;
|
|
49
|
-
reauth(): Promise<{
|
|
50
|
-
accountId: string;
|
|
51
|
-
oldAccountId: string;
|
|
52
|
-
swapped: boolean;
|
|
53
|
-
} | null>;
|
|
54
49
|
supportedCommands(): Promise<ProviderCommandInfo[]>;
|
|
55
50
|
supportedModels(): Promise<ProviderModelInfo[]>;
|
|
56
51
|
supportedAgents(): Promise<ProviderAgentInfo[]>;
|
|
@@ -57,11 +57,6 @@ export declare class AgentSession implements IAgentSession {
|
|
|
57
57
|
setPermissionMode(mode: PermissionMode): Promise<void>;
|
|
58
58
|
setSystemPrompt(basePrompt: string | undefined): boolean;
|
|
59
59
|
setCwd(cwd: string): void;
|
|
60
|
-
reauth(): Promise<{
|
|
61
|
-
accountId: string;
|
|
62
|
-
oldAccountId: string;
|
|
63
|
-
swapped: boolean;
|
|
64
|
-
} | null>;
|
|
65
60
|
getPrePlanMode(): PermissionMode | undefined;
|
|
66
61
|
setPlanExitQueueCheck(fn: () => boolean): void;
|
|
67
62
|
takePendingPlanExitSeed(): Promise<{
|
|
@@ -14,6 +14,12 @@ export interface LedgerEnsureContext {
|
|
|
14
14
|
export declare class LedgerLifecycle {
|
|
15
15
|
private writer;
|
|
16
16
|
private initAttempted;
|
|
17
|
+
private start;
|
|
18
|
+
initialize(ctx: {
|
|
19
|
+
depth?: number;
|
|
20
|
+
parentSessionId?: string;
|
|
21
|
+
cwd?: string;
|
|
22
|
+
}): void;
|
|
17
23
|
ensure(ctx: LedgerEnsureContext): void;
|
|
18
24
|
recordUser(text: string, input?: string): void;
|
|
19
25
|
recordEvent(event: OutputEvent): void;
|
|
@@ -17,11 +17,6 @@ export declare function setModel(model: AgentModelInput | undefined, deps: Confi
|
|
|
17
17
|
export declare function setPermissionMode(mode: PermissionMode, deps: ConfigDeps): Promise<void>;
|
|
18
18
|
export declare function setSystemPrompt(basePrompt: string | undefined, deps: ConfigDeps): boolean;
|
|
19
19
|
export declare function setCwd(cwd: string, deps: ConfigDeps): void;
|
|
20
|
-
export declare function reauth(deps: ConfigDeps): Promise<{
|
|
21
|
-
accountId: string;
|
|
22
|
-
oldAccountId: string;
|
|
23
|
-
swapped: boolean;
|
|
24
|
-
} | null>;
|
|
25
20
|
export declare function takePendingPlanExitSeed(deps: ConfigDeps): Promise<{
|
|
26
21
|
message: string;
|
|
27
22
|
mode: PermissionMode;
|
|
@@ -9,6 +9,14 @@ export interface SessionMeta {
|
|
|
9
9
|
startedAt?: number;
|
|
10
10
|
afkVersion?: string;
|
|
11
11
|
forkedFrom?: string;
|
|
12
|
+
gitHead?: SessionStart | null;
|
|
12
13
|
}
|
|
14
|
+
export interface SessionStart {
|
|
15
|
+
branch: string | null;
|
|
16
|
+
headSha: string | null;
|
|
17
|
+
capturedAt: number;
|
|
18
|
+
}
|
|
19
|
+
export declare function captureGitHead(cwd: string): SessionStart;
|
|
13
20
|
export declare function writeSessionMeta(meta: SessionMeta): Promise<void>;
|
|
14
21
|
export declare function readSessionMeta(sessionId: string): SessionMeta | null;
|
|
22
|
+
export declare function readSessionStart(sessionId: string): SessionStart | null;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: consumer-map
|
|
3
|
+
description: "Read-only consumer graph and blast-radius analysis — takes either a diff (PR number, patch file, git diff) or a named target (symbol, module, config key) and maps the full consumer surface: direct callers, transitive importers (depth 2), test/config/schema refs, hot paths, and event-pipeline members. Emits a scored Impact Report with a PROCEED / NARROW_SCOPE / HUMAN_GATE verdict before any mutation. Replaces blast-radius and impact-map with a single skill covering both entry points."
|
|
4
|
+
argument-hint: "<PR-number | diff-file | symbol | module | config-key> [--repo <path>] [--symbols <comma-list>]"
|
|
5
|
+
skills: [contract]
|
|
6
|
+
allowed-tools: bash, read_file, grep, glob, agent
|
|
7
|
+
failure_modes:
|
|
8
|
+
- diff mode: no diff artifact obtainable (verbal description only, no PR/patch/diff)
|
|
9
|
+
- diff mode: symbols_changed list incomplete (renamed vs. deleted not distinguished)
|
|
10
|
+
- target mode: ambiguous target (multiple symbols share the name across packages)
|
|
11
|
+
- probe context leak (framing or diff hunks accidentally included in probe prompt)
|
|
12
|
+
- uncovered entries in report (verdict emitted before all files/symbols accounted for)
|
|
13
|
+
- verdict ignored and mutations proceed without operator acknowledgment
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Overview
|
|
17
|
+
|
|
18
|
+
`consumer-map` is a pure decision-support skill. It never edits files, never commits changes, and never dispatches write-path skills. Its sole artifact is an Impact Report with a machine-readable verdict.
|
|
19
|
+
|
|
20
|
+
Two input modes, one pipeline:
|
|
21
|
+
|
|
22
|
+
- **Diff mode** — pass a PR number, patch file, or `git diff` output. The skill parses the diff to extract `files_touched` and `symbols_changed`, then maps their consumer surface. Use when you have a change and want to know what it hits.
|
|
23
|
+
- **Target mode** — pass a symbol name, module path, config key, environment variable, API endpoint, or schema column. The skill resolves the target to concrete file paths and exported symbols, then maps their consumer surface. Use when you are considering a change and want to know who depends on the target.
|
|
24
|
+
|
|
25
|
+
If the input is ambiguous — a bare number that could be a PR or a line count, a name that matches multiple distinct entities — the skill stops and asks for disambiguation before dispatching any probes.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Wave 1 — Input normalization (inline, ≤5 tool calls, no agent dispatch)
|
|
30
|
+
|
|
31
|
+
**Diff mode:**
|
|
32
|
+
Fetch the diff artifact (via `git diff`, `gh pr diff <N>`, or a passed file path) and parse it directly. Emit a structured manifest:
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{ "files_touched": [...], "symbols_changed": [...], "hunk_map": { "<file>": [[start, end], ...] } }
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`symbols_changed` captures: functions renamed or deleted, exported types modified, function signatures altered. If no diff artifact is obtainable:
|
|
39
|
+
|
|
40
|
+
> `BLOCKED: no diff artifact — run \`git diff\` or \`gh pr diff <N>\` and pass the output, or use target mode with a symbol name`
|
|
41
|
+
|
|
42
|
+
**Target mode:**
|
|
43
|
+
Resolve `<target>` to a canonical name, source file, and type (function / module / type / config key / env var / schema column / other). Populate `files_touched` with the target's source file(s) and `symbols_changed` with the target's exported names.
|
|
44
|
+
|
|
45
|
+
If `<target>` is ambiguous — multiple symbols share the name across packages or the string matches more than one distinct entity — halt immediately and request disambiguation. Do not guess.
|
|
46
|
+
|
|
47
|
+
No probe dispatch occurs before Wave 1 completes and emits a non-empty manifest.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Wave 2 — Parallel consumer probes (3 agents, simultaneous dispatch, context-blind)
|
|
52
|
+
|
|
53
|
+
All three agents are dispatched in a single tool-use block. Each is read-only and scoped to a single consumer class. Each receives only `files_touched` and `symbols_changed` from the Wave 1 manifest — **no patch framing, no bug description, no diff hunks, no stated intent of the change**. The denial of framing is the mechanism: probes cannot confirm what they cannot see.
|
|
54
|
+
|
|
55
|
+
**Probe A — Direct callers and importers**
|
|
56
|
+
For each symbol in `symbols_changed`, grep the entire repo for call sites, imports, and type references. For each file in `files_touched`, find direct importers. Returns:
|
|
57
|
+
- `callsites` — deduplicated `file:line:snippet` list, grouped by file
|
|
58
|
+
- `hot_paths` — callsites that reach user-facing surfaces, public APIs, or test fixtures
|
|
59
|
+
- `missing_coverage` — symbols with zero test-file callsites
|
|
60
|
+
- `event_pipeline_members` — if any touched file participates in an event/message pipeline, name the chain
|
|
61
|
+
|
|
62
|
+
Covers source files only (excludes test and config files — those are Probe C's domain).
|
|
63
|
+
|
|
64
|
+
**Probe B — Transitive consumers (depth 2)**
|
|
65
|
+
For each direct consumer file found by Probe A's methodology (re-derived independently — Probe B does not see Probe A's output), find their callers and importers one level up. Returns:
|
|
66
|
+
- `transitive_consumers` — second-order impact list with `file | importer_count | hub` per entry
|
|
67
|
+
- `hub` flag: files imported by ≥5 other modules
|
|
68
|
+
|
|
69
|
+
Stops at depth 2 to bound scope. If depth-2 fan-out exceeds 80 files, truncate and note `TRANSITIVE_OVERFLOW`.
|
|
70
|
+
|
|
71
|
+
**Probe C — Test, config, schema, and CI consumers**
|
|
72
|
+
Search test files, fixture data, env files, `.env.example`, CI config, migration files, schema definitions, and any JSON/YAML/TOML config referencing any symbol or file from the manifest by name or key. Returns separate sub-lists:
|
|
73
|
+
- `test_sites` — test files that exercise the target
|
|
74
|
+
- `mock_sites` — mocks, stubs, or fixture data referencing the target
|
|
75
|
+
- `config_keys` — config, env, or schema references
|
|
76
|
+
- `migration_refs` — migration files touching the target
|
|
77
|
+
- `ci_refs` — CI/CD config referencing the target
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Wave 3 — Synthesis gate (inline, no agent dispatch)
|
|
82
|
+
|
|
83
|
+
After all three probes complete, merge and deduplicate across all maps.
|
|
84
|
+
|
|
85
|
+
**Completeness check:** every entry in `files_touched` and every symbol in `symbols_changed` must appear in at least one report section before a verdict is emitted. A report with uncovered entries is incomplete — loop back to targeted re-probing (max one additional pass) before declaring `BLOCKED: incomplete coverage`.
|
|
86
|
+
|
|
87
|
+
**Classify every site:**
|
|
88
|
+
|
|
89
|
+
| Class | Source |
|
|
90
|
+
|---|---|
|
|
91
|
+
| `DIRECT` | Probe A direct import/call site |
|
|
92
|
+
| `TRANSITIVE` | Probe B second-order consumer |
|
|
93
|
+
| `TEST` | Probe C test or mock site |
|
|
94
|
+
| `CONFIG` | Probe C config, env, schema, or migration ref |
|
|
95
|
+
| `EXTERNAL` | Any site outside the repo root (submodule, vendored dep) |
|
|
96
|
+
|
|
97
|
+
**Compute impact score:**
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
score = (direct_count × 3) + (transitive_count × 1) + (test_count × 0.5) + (config_count × 0.5)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Map score to tier:**
|
|
104
|
+
|
|
105
|
+
| Score | Tier |
|
|
106
|
+
|---|---|
|
|
107
|
+
| < 5 | `LOW` |
|
|
108
|
+
| 5–14 | `MEDIUM` |
|
|
109
|
+
| 15–39 | `HIGH` |
|
|
110
|
+
| ≥ 40 | `CRITICAL` |
|
|
111
|
+
|
|
112
|
+
**Map tier to verdict:**
|
|
113
|
+
|
|
114
|
+
| Tier | Verdict |
|
|
115
|
+
|---|---|
|
|
116
|
+
| `LOW` or `MEDIUM` | `PROCEED` — consumer surface is well-understood |
|
|
117
|
+
| `HIGH` | `NARROW_SCOPE` — recommend scoping the change to a subset of consumers before invoking a write-path skill |
|
|
118
|
+
| `CRITICAL` | `HUMAN_GATE` — do not dispatch refactor/forge/mint until a human reviews the report |
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Output structure
|
|
123
|
+
|
|
124
|
+
Emit a single structured Impact Report:
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
## Impact Report
|
|
128
|
+
|
|
129
|
+
### Input mode ← diff | target
|
|
130
|
+
### Files touched (N) ← from Wave 1
|
|
131
|
+
### Symbols changed (N) ← from Wave 1
|
|
132
|
+
### Consumer map ← table of file | class | distance | hub | safe-to-ignore
|
|
133
|
+
### Hot paths at risk ← callsites reaching public API / user surface (Probe A)
|
|
134
|
+
### Blast-radius amplifiers ← shared utilities (≥3 importers) + event pipeline members (Probe A)
|
|
135
|
+
### Transitive reach ← hub files + depth-2 fan-out summary (Probe B)
|
|
136
|
+
### Test and config surface ← test_sites, mock_sites, config_keys, migration_refs, ci_refs (Probe C)
|
|
137
|
+
### Coverage gaps ← symbols with zero test callsites (Probe A)
|
|
138
|
+
### Safe zones ← modules/directories confirmed to have no dependency on the target
|
|
139
|
+
### Impact tier ← LOW | MEDIUM | HIGH | CRITICAL with score breakdown
|
|
140
|
+
### Verdict ← PROCEED | NARROW_SCOPE | HUMAN_GATE
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
For `NARROW_SCOPE`: append a **Regression test list** — the specific test files and test names that cover the affected callsites, derived from Probe A's `callsites` map and Probe C's `test_sites`. These are mandatory reading for anyone applying the change.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Decision gates
|
|
148
|
+
|
|
149
|
+
- **Ambiguous input** → stop before Wave 1, request disambiguation. Do not guess.
|
|
150
|
+
- **CRITICAL tier** → emit `HUMAN_GATE` and halt. Do not chain into any write-path skill automatically.
|
|
151
|
+
- **TRANSITIVE_OVERFLOW** → flag in report, cap transitive list at 80 entries, note that the true impact is larger than scored.
|
|
152
|
+
- **Empty result** (zero consumers found) → report `LOW` tier but note the search surface so the caller can judge whether the grep was exhaustive.
|
|
153
|
+
- **Incomplete probe** — if any Wave 2 probe does not return within its timeout, mark that consumer class as `INCOMPLETE` in the report rather than silently omitting it. An `INCOMPLETE` class cannot count toward a `PROCEED` verdict — the tier is computed on known data, but the verdict is capped at `NARROW_SCOPE` until the incomplete class is resolved.
|
|
154
|
+
- **Uncovered entries** — if the completeness check fails after one re-probe pass, emit `BLOCKED: incomplete coverage` rather than a tier verdict on partial data.
|
|
@@ -38,6 +38,18 @@ Until the verifier returns `CONFIRMED`, the convergent recommendation is a **can
|
|
|
38
38
|
|
|
39
39
|
**Scope guard:** skip when the proposal is purely local with no composition surface, or is anchored to an external referent that survives independently of the system. Does not fire when `dissent = true` — that path surfaces the matrix directly; adding a Wave 3.5 gate on already-uncertain output adds friction without signal. Fires once per convergent verdict, not per critic.
|
|
40
40
|
|
|
41
|
+
**Post-synthesis annotation — Consumer surface (inline, no dispatch):**
|
|
42
|
+
After Wave 3 picks a recommendation — and after Wave 3.5 resolves, if it fired — the coordinator runs an inline consumer-surface check before surfacing. This is deterministic coordinator work, not a sub-agent dispatch.
|
|
43
|
+
|
|
44
|
+
1. **Trigger:** fires only when the final recommendation names concrete code symbols (function, class, type, exported name) or file paths. If the recommendation is purely conceptual (an architectural stance, a process change, a scoping decision with no named code artifact), skip entirely.
|
|
45
|
+
2. **Skip on dissent:** when `dissent = true`, the matrix is surfaced directly and the operator makes the call. Adding consumer counts to an already-uncertain matrix adds noise, not signal.
|
|
46
|
+
3. **Extraction:** from the recommendation text, extract only the exported symbol names and/or file paths it references. Do not extract from the rationale, critic outputs, or the original proposal — the annotation checks the recommendation's own named targets, nothing more.
|
|
47
|
+
4. **Bounded grep:** run at most 5 grep/glob calls against the repo to count importers of each extracted symbol or file. Use the ≥3 importer threshold for `shared_utilities` — a file imported by fewer than 3 modules is not a shared utility and does not warrant annotation.
|
|
48
|
+
5. **Append:** add a `Consumer surface:` line to the recommendation output. For each symbol or file that meets the ≥3 threshold, show `<name> — <N> importers (search scope: <glob used>)`. For symbols below the threshold, omit them. If no concrete symbols were extractable from the recommendation, write `Consumer surface: not checked`. If symbols were extracted and checked but none met the ≥3 threshold, write `Consumer surface: checked — no symbol ≥3 importers (scope: <glob used>)`. Never write `accounted` or any verdict that implies completeness.
|
|
49
|
+
6. **Defer:** when any symbol shows ≥3 importers, append: `For the full consumer graph, run /consumer-map <target> or /consumer-map <PR-number>.` This annotation is a lightweight signal, not a substitute for that skill.
|
|
50
|
+
|
|
51
|
+
**Why not a verdict:** grep-only coverage misses dynamic imports, string-keyed config references, event-pipeline membership, and transitive consumers beyond one level. Emitting `ACCOUNTED` or `BLIND_SPOT` on incomplete evidence would create false assurance or false alarm. Raw counts with explicit search scope let the operator and downstream skills make their own judgment.
|
|
52
|
+
|
|
41
53
|
**Merge + surface:**
|
|
42
54
|
- Recommendation = `original` → the proposal survived critique; proceed with it. **With a steelman annotation present, the strengthened form is what survived and is therefore what you proceed with** — it is the artifact Wave 3 actually scored, and executing the verbatim text instead would run a version that never won: one that can omit a prerequisite the steelman made explicit, or reinstate a claim it dropped as indefensible. Rank and execute must name the same artifact. Surface it **as** the strengthened version, with `gaps_filled` (assumptions the proposal depends on but never stated) and `weak_claims_dropped` (claims too weak to defend) shown as an explicit delta against what the user wrote, so they can see exactly what changed and reject it if they disagree. The substitution must be **visible, never silent** — do not present strengthened text as if it were the user's verbatim proposal. With no steelman annotation, `original` is the verbatim proposal and proceeds unchanged.
|
|
43
55
|
- Recommendation ≠ `original`, `dissent = false`, ≥2 critics returned the same alternative → convergent path: run Wave 3.5, then surface the alternative with rationale (on `OVERRIDE`, re-rank first) before acting.
|
|
@@ -12,7 +12,7 @@ failure_modes:
|
|
|
12
12
|
## Sub-agent contract
|
|
13
13
|
/contract
|
|
14
14
|
|
|
15
|
-
**Constraint: read-only reconnaissance.** You MUST NOT call `edit_file`, `write_file`, or any mutating bash command (no `git commit`, `git push`, `git checkout`, `mv`, `rm`, file redirection, package installs, etc.). Read-only tools only: `read_file`, `grep`, `glob`, `list_directory`, `memory_search`, and
|
|
15
|
+
**Constraint: read-only reconnaissance.** You MUST NOT call `edit_file`, `write_file`, or any mutating bash command (no `git commit`, `git push`, `git checkout`, `mv`, `rm`, file redirection, package installs, etc.). Read-only tools only: `read_file`, `grep`, `glob`, `list_directory`, `memory_search`, and git queries (via `bash` or `git_read` when bash is unavailable). Under `git_read`, non-git shell commands (`cat`, `ls`, `stat`, `tail`) are not available; use `read_file`, `glob`, and `list_directory` instead. `memory_search` is non-mutating and is the **only** way to reach the cross-session fact archive — it is in scope for this skill, do not strip it from this list.
|
|
16
16
|
|
|
17
17
|
If the survey reveals a fix that's tempting to apply, **return it as a recommendation in the snapshot** — the orchestrator decides whether to act. Even if the invoking brief sounds prescriptive ("draft the edit", "apply the change"), this skill stops at the snapshot and the preamble artifact. The orchestrator dispatches a separate implementation step afterward.
|
|
18
18
|
|
|
@@ -48,7 +48,7 @@ Check for relevant tooling and configs. Use the domain table below to decide whi
|
|
|
48
48
|
|
|
49
49
|
| Domain | What to scan |
|
|
50
50
|
|--------|-------------|
|
|
51
|
-
| `software` | CI configs (`
|
|
51
|
+
| `software` | CI configs (`list_directory` or `glob` on `.github/workflows/`), package scripts (`package.json`, `Makefile`, `pyproject.toml`), linters/formatters, authoritative config files for the task. |
|
|
52
52
|
| `research` | Reference manager (.bib files), LaTeX setup, data analysis tools (Jupyter, R scripts), collaboration setup. |
|
|
53
53
|
| `design` | Design tool configs, prototyping tools, handoff configs (Storybook), asset pipeline scripts. |
|
|
54
54
|
| `business` | Modeling tool configs, presentation formats, data source configs, collaboration tool structure. |
|
|
@@ -66,14 +66,11 @@ Return: relevant facts with 1-line summaries, **plus the stores actually consult
|
|
|
66
66
|
|
|
67
67
|
Read `SPINE.md` from the repo root (same directory as `AFK.md`). If the file does not exist or is empty, skip silently -- do not mention it in the snapshot. If it exists and has entries, extract its invariant (INV-*), rejected-pattern (REJ-*), and taste entries (TST-*) and include them in the snapshot so architectural constraints are visible before proposing changes.
|
|
68
68
|
|
|
69
|
-
### Eval-pipeline recency survey *(
|
|
69
|
+
### Eval-pipeline recency survey *(software domain only)*
|
|
70
70
|
|
|
71
71
|
For software-domain sessions, check whether the eval-run pipeline is current. This guard catches silent regressions that accumulate when the pipeline goes unrun during high-velocity sprints.
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
```
|
|
75
|
-
tail -1 ~/.afk/agent-framework/improve/eval-runs/.index.jsonl 2>/dev/null
|
|
76
|
-
```
|
|
73
|
+
Read the last line of `~/.afk/agent-framework/improve/eval-runs/.index.jsonl` (use `read_file`; if the file does not exist, treat as "never run").
|
|
77
74
|
|
|
78
75
|
Parse the `timestamp` field from the output. Then compute the age in days relative to today's date.
|
|
79
76
|
|
|
@@ -110,8 +107,8 @@ After the snapshot is assembled, construct the **Brief Anchor** — a path-verif
|
|
|
110
107
|
|
|
111
108
|
**Construction procedure:**
|
|
112
109
|
|
|
113
|
-
1. From your state survey output, extract the verified `cwd` (
|
|
114
|
-
2. From your infrastructure survey output, extract the 2–4 canonical file paths most relevant to the task. For each,
|
|
110
|
+
1. From your state survey output, extract the verified `cwd` (from `git rev-parse --show-toplevel` combined with `git rev-parse --show-prefix` to reconstruct the full session path: `<toplevel>/<prefix>`), `branch` (from `git rev-parse --abbrev-ref HEAD`), and `HEAD` SHA (from `git rev-parse HEAD`).
|
|
111
|
+
2. From your infrastructure survey output, extract the 2–4 canonical file paths most relevant to the task. For each, verify existence with `glob` or `read_file`; include the path only if it exists. Paths that don't exist are omitted; if zero paths survive, set the list to `(none verified)`.
|
|
115
112
|
3. Assemble the preamble block:
|
|
116
113
|
|
|
117
114
|
```
|
|
@@ -119,7 +116,7 @@ After the snapshot is assembled, construct the **Brief Anchor** — a path-verif
|
|
|
119
116
|
- **cwd**: <absolute path>
|
|
120
117
|
- **branch**: <branch name>
|
|
121
118
|
- **HEAD**: <full SHA>
|
|
122
|
-
- **canonical paths** (
|
|
119
|
+
- **canonical paths** (verify each on entry; emit GROUNDING_FAILED:<path> and abort if missing):
|
|
123
120
|
- <verified_path_1>
|
|
124
121
|
- <verified_path_2> ← omit line if not applicable
|
|
125
122
|
```
|
|
@@ -129,7 +126,7 @@ After the snapshot is assembled, construct the **Brief Anchor** — a path-verif
|
|
|
129
126
|
**Orchestrator usage contract:**
|
|
130
127
|
|
|
131
128
|
- Prepend the Brief Anchor verbatim to every sub-agent brief that reads files, runs `git`/`gh` commands, or references explicit paths. Skip for pure-reasoning tasks.
|
|
132
|
-
- Sub-agents receiving the anchor
|
|
129
|
+
- Sub-agents receiving the anchor verify each listed path on entry (via `glob` or `read_file`). A missing path returns `GROUNDING_FAILED:<path>` — the orchestrator re-dispatches once with the corrected path. If the retry also returns `GROUNDING_FAILED`, emit `BRIEF_GROUND_ABORT` with both the expected and actual paths **plus the corrective command** the operator should run — `git worktree list` to find the intended checkout, then `cd <correct-worktree>` — and halt the wave.
|
|
133
130
|
- The anchor is session-scoped: one construction pass per `ground-state` invocation. Do not re-invoke `ground-state` mid-session to refresh it; instead pass the existing anchor through.
|
|
134
131
|
|
|
135
132
|
**Skip when:**
|