feat(core): make path-local instruction discovery durable

Replace synthetic-message instruction injection with a durable
discovery projection so discovered AGENTS.md files survive compaction,
forks, reverts, and restarts.

- Add the instruction_file table and the durable
  session.instructions.discovered event; projection stores each
  discovered path and content with its owning assistant-message
  boundary and durable discovery order.
- Fold discovered files into the core/instructions source through
  InstructionDiscovery, absorbing SessionInstructions. Completed
  compaction rebaselines restate discovered instructions instead of
  summarizing them away.
- Re-read discovered files live at each observation so mid-session
  edits reach the model; the frozen discovery content stands in only
  when a file becomes unreadable.
- Narrate instruction file changes as per-file deltas via diffByKey,
  restating the full set only for pure reorderings.
- Fork copies discoveries within the inherited transcript, committed
  revert removes discoveries past the revert boundary, and Session
  movement clears them so the destination initializes a complete
  baseline.
This commit is contained in:
Kit Langton 2026-07-06 14:22:53 -04:00
commit 0726f09b05
28 changed files with 1166 additions and 598 deletions

View file

@ -26,6 +26,7 @@ export type Event =
| EventSessionPromptAdmitted
| EventSessionExecutionSettled
| EventSessionInstructionsUpdated
| EventSessionInstructionsDiscovered
| EventSessionSynthetic
| EventSessionSkillActivated
| EventSessionShellStarted
@ -935,6 +936,19 @@ export type GlobalEvent = {
text: string
}
}
| {
id: string
type: "session.instructions.discovered"
properties: {
sessionID: string
assistantMessageID: string
location: LocationRef
files: Array<{
path: string
content: string
}>
}
}
| {
id: string
type: "session.synthetic"
@ -1732,6 +1746,7 @@ export type GlobalEvent = {
| SyncEventSessionPromptPromoted
| SyncEventSessionPromptAdmitted
| SyncEventSessionInstructionsUpdated
| SyncEventSessionInstructionsDiscovered
| SyncEventSessionSynthetic
| SyncEventSessionSkillActivated
| SyncEventSessionShellStarted
@ -2895,6 +2910,7 @@ export type SessionDurableEvent =
| SessionPromptPromoted
| SessionPromptAdmitted
| SessionInstructionsUpdated
| SessionInstructionsDiscovered
| SessionSynthetic
| SessionSkillActivated
| SessionShellStarted
@ -3036,6 +3052,7 @@ export type V2Event =
| SessionPromptAdmitted
| SessionExecutionSettled
| SessionInstructionsUpdated
| SessionInstructionsDiscovered
| SessionSynthetic
| SessionSkillActivated
| SessionShellStarted
@ -3758,6 +3775,26 @@ export type SyncEventSessionInstructionsUpdated = {
}
}
export type SyncEventSessionInstructionsDiscovered = {
type: "sync"
id: string
syncEvent: {
type: "session.instructions.discovered.1"
id: string
seq: number
aggregateID: string
data: {
sessionID: string
assistantMessageID: string
location: LocationRef
files: Array<{
path: string
content: string
}>
}
}
}
export type SyncEventSessionSynthetic = {
type: "sync"
id: string
@ -4702,6 +4739,30 @@ export type SessionInstructionsUpdated = {
}
}
export type SessionInstructionsDiscovered = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
type: "session.instructions.discovered"
durable: {
aggregateID: string
seq: number
version: number
}
location?: LocationRef
data: {
sessionID: string
assistantMessageID: string
location: LocationRef
files: Array<{
path: string
content: string
}>
}
}
export type SessionSynthetic = {
id: string
created: number
@ -6834,6 +6895,20 @@ export type EventSessionInstructionsUpdated = {
}
}
export type EventSessionInstructionsDiscovered = {
id: string
type: "session.instructions.discovered"
properties: {
sessionID: string
assistantMessageID: string
location: LocationRef
files: Array<{
path: string
content: string
}>
}
}
export type EventSessionSynthetic = {
id: string
type: "session.synthetic"
@ -8409,6 +8484,30 @@ export type SessionInstructionsUpdated2 = {
}
}
export type SessionInstructionsDiscovered2 = {
id: string
created: number
metadata?: {
[key: string]: unknown
}
type: "session.instructions.discovered"
durable: {
aggregateID: string
seq: number
version: number
}
location?: LocationRef2
data: {
sessionID: string
assistantMessageID: string
location: LocationRef2
files: Array<{
path: string
content: string
}>
}
}
export type SessionSynthetic2 = {
id: string
created: number
@ -8990,6 +9089,7 @@ export type SessionDurableEventV2 =
| SessionPromptPromoted2
| SessionPromptAdmitted2
| SessionInstructionsUpdated2
| SessionInstructionsDiscovered2
| SessionSynthetic2
| SessionSkillActivated2
| SessionShellStarted2
@ -11180,6 +11280,7 @@ export type V2EventV2 =
| SessionPromptAdmitted2
| SessionExecutionSettled2
| SessionInstructionsUpdated2
| SessionInstructionsDiscovered2
| SessionSynthetic2
| SessionSkillActivated2
| SessionShellStarted2