Skip to content

feat(synthesizer): Stage 5 — opt-in --generate / AIF_RESEARCH=llm live-LLM wiring (#646) - #691

Merged
artyhoo merged 1 commit into
stagingfrom
feature/tmp-1ad156
Jun 23, 2026
Merged

feat(synthesizer): Stage 5 — opt-in --generate / AIF_RESEARCH=llm live-LLM wiring (#646)#691
artyhoo merged 1 commit into
stagingfrom
feature/tmp-1ad156

Conversation

@artyhoo

@artyhoo artyhoo commented Jun 23, 2026

Copy link
Copy Markdown
Owner

Stage 5 — final stage of the stage-2-generate-path umbrella (#646)

Wires the opt-in live-LLM seams for the rules-factory. Consumers can now generate enforcement rules with a live LLM on their own subscription, install-time, never in CI; the deterministic v1 path stays byte-identical when opted out.

Deliverables

  • D1 generate-adapter-anthropic.ts (NEW) — live Anthropic GenerateClient (createAnthropicGenerateClient). Mirrors menu-pick-adapter-anthropic.ts; native fetch, zero new deps; never imported by any *.test.ts. Path A enforced in the prompt (configures EXISTING ESLint rules, never invents a selector / authors TS).
  • D2 generate-cli.ts (NEW) — runGeneratePath(): synthesizeGenerate → L4 validate()degrade to research-only when L4 rejects every generated rule. The testable seam.
  • D3 cli.ts--generate flag (live generate-path + L4-degrade) and AIF_RESEARCH=llm env (live research client). loadPlan/main async; --from-research still wins; opted-out path is byte-identical to v1.
  • D4 generate-cli.test.ts (NEW) — paired-negative wiring tests (principle 02) via injected stubs only (stubGenerateRN → synthesis; stubGenerateBad → research-only degrade).

Hard constraints honored

  • L4/L5 byte-identical — no edits under validator/ or installer/; the degrade is a CLI-layer read of validate().ok.
  • Zero paid-LLM-in-CI — live adapters never imported by tests; grep-verified clean.
  • Zero new npm deps — native fetch.
  • Curated presets byte-identical — synthesizer/validator snapshot tests green.

Verification (clean-checkout, orchestrator T19)

  • synthesizer/ validator/ → 88/88 ✅ (incl. byte-identical snapshots)
  • principles → 226/226 ✅ (02 paired-negative, 03 ast-over-grep)
  • grep adapter-anthropic packages/core/**/*.test.ts → no leak ✅
  • (the make self-audit principle-20 timeout is a known /tmp-worktree load artifact — passes standalone; this diff touches only packages/core/synthesizer/)

Built autonomously via aif-handoff; cold-QA'd + clean-checkout-verified by the orchestrator before harvest.

…e-LLM wiring

Wire the opt-in seams for the live-LLM rules-factory paths:
- D1 generate-adapter-anthropic.ts — live Anthropic GenerateClient (install-time
  only; mirrors menu-pick-adapter-anthropic.ts; never imported by any *.test.ts).
- D2 generate-cli.ts — runGeneratePath: synthesizeGenerate → L4 validate → degrade
  to research-only when L4 rejects all generated rules. The testable seam.
- D3 cli.ts — --generate flag (live generate-path + L4-degrade) and AIF_RESEARCH=llm
  env (live research client); loadPlan/main async; opted-out path byte-identical.
- D4 generate-cli.test.ts — paired-negative wiring tests via injected stubs only.

L4/L5 untouched — the degrade is a CLI-layer decision reading validate().ok.

Prior-art: prior-art-evaluations.md#66 — Stage 5 wires the BUILD-verdict L3-live generate-path (createAnthropicGenerateClient) + L2-live research opt-in behind --generate/AIF_RESEARCH=llm; /aif-evolve is REFERENCE so our synthesizer stays BUILD (#66 cross-link). REUSE existing L4 validate() (#154 RuleTester ADOPT) as the degrade gate — validator untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@artyhoo
artyhoo enabled auto-merge (squash) June 23, 2026 10:55
@artyhoo
artyhoo merged commit 0ee369a into staging Jun 23, 2026
23 checks passed
artyhoo added a commit that referenced this pull request Jun 23, 2026
#692)

Prior-art: skipped — umbrella closure marker (done.md, 4-line completion record), doc-only, no new capability per CLAUDE.md escape hatch.
artyhoo added a commit that referenced this pull request Jun 26, 2026
… issue #646 sequencing commitment (#726)

Stage 2 (stage-2-generate-path, #668-#691) built the live-LLM generate-path
— the first real LLM v2 invocation in L2/L3 — but never updated open-questions
§13.10, which still read 'OPEN, v2 trigger'. Doc-vs-reality drift: the SSOT for
trigger conditions said 'not yet invoked' while the path was live and merged.

- New research-patch records the firing + the missing sequencing-commitment
  artifact mandated by #646 (the *-phase-5-v2-trigger-fired.md the hybrid
  decision required at Stage 1 close).
- §13.10 areas 1 (L2 research) + 2 (Path A L3 gen) → FIRED via Stage 2, Path A
  only; areas 3/4/5 (Path B, Gate 5, Stryker) stay OPEN (out-of-scope-HARD).
- §13.11 cost-model trigger noted fired; infra stays deferred ($0 install-time
  on consumer subscription, no CI billing).

Prior-art: skipped — docs only, no new capability/dependency/code module (records an already-merged trigger firing; per CLAUDE.md doc edits are not capability commits).
artyhoo added a commit that referenced this pull request Jul 21, 2026
…OR live-fire + Prior-art #225 (#1084)

S4 (umbrella closure) discharges the BFR §3 obligation for the ir-unfreeze
relational-IR capability (landed across S1–S3) and closes the S2 carry-forward M3
(the multi-child not:{any} fold had render-golden coverage only, no committed
live-fire). No IR-shape re-decision, no consumer migration.

Sweep (confirm-not-migrate): `git grep -l ConventionNode -- 'packages/core/**/*.ts'
| grep -v test` = 24 consumers; `tsc --noEmit -p packages/core/tsconfig.json` exit 0
proves every consumer type-checks under the Option B discriminated union.
Bucket A (7 read the relational plane): ir/types.ts (the definition), ir/gates/
grammar.ts (FF6004 switch+assertNever), backends/astgrep/render-astgrep.ts
(renderRelationalNode switch+assertNever), backends/{cargo,npm,ruff} (FF7001
presence-refuse — the honest S3 boundary, not a gap), diagnostics/registry.ts
(FF-code registration). Exhaustiveness rests on the 2 op-switch sites (grammar.ts,
render-astgrep.ts) whose assertNever(x: never) default forces TS2355 on any
unhandled arm; the 3 refuse-sites read presence only. Bucket B (17 never read
.relational): correct-by-construction — the field is OPTIONAL and absent on every
legacy scalar node. ZERO of the 24 files edited for migration; byte-lock
(synthesizer/to-node.test.ts) stays green.

Multi-child live-fire (closes S2 M3): census-grounded NOR
"require-return-type-or-docstring" (flag functions with NEITHER a return-type hint
NOR a docstring). MULTI_CHILD_FIXTURE_NODE renders not:{any:[has type $T, has string
$DOC]}. Real @ast-grep/cli 0.44.1 scan: RED (neither) exit 1 / GREEN (-> int) exit 0;
the NOR control proves the any-fold is behaviourally load-bearing — a docstring-only
source under the rendered not:{any} = 0 findings, under the wrong not:{all} swap = 1
finding. Arm B string-kind IMPLEMENTER-PINNED live (T12); the raise-based fallback was
not needed.

SSOT: append-only row #225 (ADAPT — ast-grep's any/all/not/has vocabulary borrowed,
the type-safe recursive discriminated-union shape is ours; distinct capability-area
from #212 emission-target ADOPT). Umbrella closure: done.md is NOT written in
this feature commit — per CLAUDE.md "Umbrella closure convention" + repo precedent
(762b2d3 PR #904, c035a94 PR #691) the merging session authors it as a separate
post-merge commit carrying the real Final PR number, not a TBD placeholder baked here.

python-data-only; rust expressibility remains a stated GAP (never a coverage claim).

Prior-art: prior-art-evaluations.md#225 (relational ConventionNode IR = ADAPT of ast-grep's any/all/not/has relational vocabulary — vocabulary borrowed, the type-safe discriminated-union shape is ours; distinct capability-area from #212 ast-grep emission-target ADOPT).

Co-authored-by: t <t@t.co>
artyhoo added a commit that referenced this pull request Jul 21, 2026
Umbrella closure marker per CLAUDE.md «Umbrella closure convention», authored
by the merging session at last-stage merge with the real Final PR number
(deferred from the S4 feature commit to avoid a #TBD placeholder, per precedent
PR #904/#691). Enables priority-score.sh Layer C3 completion-detection.

Prior-art: skipped — orchestrator-prompt closure marker, no new capability (not under packages/; done.md is header-exempt per doc-authority-hierarchy.md §2).

Co-authored-by: t <t@t.co>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant