Thread per-commitment enforcement level through to the snapshot
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -147,14 +147,15 @@ type Controller struct {
|
||||
carryForward string // latest-wins takeaway; grounds the next coach
|
||||
reflectionGen int
|
||||
|
||||
allowedClasses []string // durable: the active session's allowed window classes
|
||||
judge ai.DriftJudge
|
||||
driftStatus string
|
||||
driftReason string
|
||||
driftGen int
|
||||
nudgeEpoch int // identifies the current on-task stretch; nudge staleness guard
|
||||
lastJudgedAt time.Time
|
||||
judgedClasses map[string]ai.Verdict
|
||||
allowedClasses []string // durable: the active session's allowed window classes
|
||||
enforcementLevel domain.EnforcementLevel // durable: block enables window-minimize enforcement
|
||||
judge ai.DriftJudge
|
||||
driftStatus string
|
||||
driftReason string
|
||||
driftGen int
|
||||
nudgeEpoch int // identifies the current on-task stretch; nudge staleness guard
|
||||
lastJudgedAt time.Time
|
||||
judgedClasses map[string]ai.Verdict
|
||||
|
||||
nudge ai.Nudger
|
||||
recentTitles []string // in-memory ring of recent distinct titles this session
|
||||
@@ -286,6 +287,7 @@ func New(snapshotPath string) (*Controller, error) {
|
||||
_ = store.PruneOlderThan(c.sessionsDir, sessionRetention, c.clock())
|
||||
if c.runtimeState == domain.RuntimeActive && s.SessionID != "" {
|
||||
c.allowedClasses = s.AllowedWindowClasses
|
||||
c.enforcementLevel = s.EnforcementLevel
|
||||
// Drift state is not persisted: recompute fresh after restart to avoid
|
||||
// stale interrupts. This also initializes judgedClasses (the pipeline
|
||||
// writes to it) so a restored Active session never panics on a nil map.
|
||||
@@ -432,6 +434,7 @@ func (c *Controller) persistLocked() error {
|
||||
snap.SessionID = c.stats.SessionID
|
||||
}
|
||||
snap.AllowedWindowClasses = c.allowedClasses
|
||||
snap.EnforcementLevel = c.enforcementLevel
|
||||
snap.ReflectionStatus = c.reflectionStatus
|
||||
snap.ReflectionRecap = c.reflectionRecap
|
||||
snap.CarryForward = c.carryForward
|
||||
@@ -701,6 +704,14 @@ func (c *Controller) AllowedClassesForTest() []string {
|
||||
return append([]string(nil), c.allowedClasses...)
|
||||
}
|
||||
|
||||
// EnforcementLevelForTest exposes the active session's enforcement level. Tests
|
||||
// only.
|
||||
func (c *Controller) EnforcementLevelForTest() domain.EnforcementLevel {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
return c.enforcementLevel
|
||||
}
|
||||
|
||||
// SetDriftJudge injects the AI drift judge. A nil judge keeps local matching
|
||||
// working; unmatched windows simply stay idle.
|
||||
func (c *Controller) SetDriftJudge(j ai.DriftJudge) {
|
||||
@@ -867,7 +878,7 @@ func coachErrorMessage(err error) string {
|
||||
// StartManualCommitment validates input, activates a new commitment, mints a
|
||||
// session, seeds evidence stats from the latest window, and moves Planning ->
|
||||
// Active.
|
||||
func (c *Controller) StartManualCommitment(nextAction, successCondition string, timebox time.Duration, allowedClasses []string) error {
|
||||
func (c *Controller) StartManualCommitment(nextAction, successCondition string, timebox time.Duration, allowedClasses []string, level domain.EnforcementLevel) error {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
commitment, err := domain.NewManual(nextAction, successCondition, timebox)
|
||||
@@ -889,6 +900,7 @@ func (c *Controller) StartManualCommitment(nextAction, successCondition string,
|
||||
c.outcomePending = ""
|
||||
c.resetCoachLocked()
|
||||
c.allowedClasses = append([]string(nil), allowedClasses...)
|
||||
c.enforcementLevel = level
|
||||
c.resetDriftLocked()
|
||||
|
||||
sessionID := "session-" + uuid.Must(uuid.NewV7()).String()
|
||||
@@ -956,6 +968,7 @@ func (c *Controller) End() error {
|
||||
c.stats = nil
|
||||
c.outcomePending = ""
|
||||
c.allowedClasses = nil
|
||||
c.enforcementLevel = ""
|
||||
c.resetDriftLocked()
|
||||
return c.persistLocked()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user