feat(cli): self-improving printed CLIs - default-on self-healing learn loop#3434
Open
mvanhorn wants to merge 23 commits into
Open
feat(cli): self-improving printed CLIs - default-on self-healing learn loop#3434mvanhorn wants to merge 23 commits into
mvanhorn wants to merge 23 commits into
Conversation
…ables, decouple FTS pin
…edit for learn loop
… and run-sync warning
…al-key playbook lookup and lazy rekey
…purge and teach promotion
…two-step next actions
…urnal episodes at teach time
…nest mcp:local-write annotations
…, and forget cascade
…al-write hints on teach and confirm
…nt-only shape with kill criteria
…ilent events; harness proves the incident heals
Contributor
|
Too many files changed for review. ( Bypass the limit by tagging |
Contributor
Merge Protections🔴 2 of 2 protections blocking · waiting on 🤖 CI and 🙋 you
🔴 require-ready-label-and-ciWaiting for
This rule is failing.
🔴 🚦 Auto-queueWaiting for
This rule is failing.When all merge protections are satisfied and these conditions match, this pull request will be queued automatically.
|
… by edit distance When a failed flag has no recorded did-you-mean suggestion, infer the correction from the single new flag introduced by the successful retry (closest by edit distance; ambiguous ties skipped). Cap acceptance at min(len(failed), len(candidate))/2 (floor 1) so an unrelated new success flag (e.g. --sport when --date failed) is not promoted as a spurious flag_alias. Adds positive and negative test coverage. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4eADiHsstb6svS3iqsK4f
UpsertLearning/ListLearnings/ForgetLearnings and the teach.go call chain now thread context.Context (BeginTx/QueryContext/ExecContext) so Ctrl-C can interrupt teach writes and reads. This fix shipped hand-patched in a published CLI but was never upstreamed into the templates; without it, a reprint under the current press regresses ctx propagation. Regenerated learn-loop goldens. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4eADiHsstb6svS3iqsK4f
Pre-existing findings surfaced once .golangci.yml adopted the modernize
linter: interface{} -> any, strings.Split -> strings.SplitSeq, and an
if/assign -> min. No behavior change.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q4eADiHsstb6svS3iqsK4f
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Make every printed CLI self-improving, on by default. PR #2440 ported the self-teaching loop into the generator templates a month ago, but enablement was opt-in via a spec block no skill authored, so zero fresh prints carried it (0 of 37 local library CLIs had
internal/learn/). And where the loop did exist, its capture side was passive: a real two-session ESPN incident showed the CLI observing every failure signal (an unknown--dateflag, a World Cup league code absent from print-time seeds, phrasing-split query families, no playbook recorded) and doing nothing with any of it, so each session re-derived ~70s of identical discovery.This turns the loop on for every fresh print AND makes it self-healing: the CLI journals its own invocations, derives correction candidates from its own failures, synthesizes playbooks from the discovery a session actually ran, and surfaces them for the agent to confirm - no agent-volunteered protocol required. Local-only measurement (
learnings stats+ alearn_eventstable) with pre-registered numeric kill criteria decides whether the loop earns its keep.Approach
18 implementation units in one branch, flip landing last so no print is default-on before the quality bar is met:
ApplyLearnLoopDefaultat theGenerate()entry only (neverGenerateMCPSurface- mcp-sync must not flip learn onto published CLIs that lack the package);learn.disabled: trueopt-out; store auto-promoted instead of hard-erroring;x-learnOpenAPI extension.learn_candidateslifecycle (confirm prints the payload before materializing; reject tombstones), recall envelopecandidates[]with two-step byte-exact next-actions, same-referent phrasing folding with lazy rekey, entity-lookup refresh from synced data (the World Cup root cause).mcp:local-writeannotations plus a telemetry-class read-only carve-out in AGENTS.md, MCPcontext-tool protocol parity from one shared source, PII warn-scan at teach time, behavioral scorecard credit replacing the presence sentinel.learn_events(row-id joined),learnings stats, forget-cascades-events, 30-day kill-criteria clock baked into every generated AGENTS.md.learn_candidates+learn_events);resourcesFTSContentSchemaVersiondecoupled and pinned so reprints never trigger an FTS rebuild.Verification
go test ./...green (full suite, unscoped).scripts/golden.sh verify31/31 (intentional full regen for default-on; newgenerate-learn-disabled-apicase pins the opt-out shape).scripts/verify-generator-output.sh10/10,scripts/verify-learn-purity.sh52/52,go vetclean.TestIncidentReplay) proves AE1-AE7 end to end against a generated CLI, including the session-B-invocations-<=-50%-of-session-A gate and the pid-lineage session-key fallback.testdata/loops.yaml(a genuinely thin, POST-heavy, forced-store API): the incident heals end to end - recall miss -> fail--agen-> correct--agent-> the CLI derives a flag_alias candidate with the right family anchor -> recall surfaces it with a two-step next-action ->learnings confirmmaterializes the correction into the family playbook notes; verify-env runs write zero events and zero journal segments; 8 quality gates pass.Cross-repo lockstep
Tracking issue filed at mvanhorn/printing-press-library#1425 (schema/package-shape changes + sweep anchors) per the AGENTS.md learn-template lockstep rule. ESPN hand-port via regen-merge is a separate PR (the proving vehicle); the other ~35 published CLIs are deferred to the sweep.
AI / Automation Disclosure
Plan (local, gitignored): docs/plans/2026-07-02-002-feat-self-improving-learn-loop-unified-plan.md
🤖 Generated with Claude Code
https://claude.ai/code/session_019LMUA4Az5S9hvnaPfDt4W1