Skip to content

Score runtime (D5): manifests, router, entitlements, stage guard, usage capture - #76

Draft
aarontrowbridge wants to merge 20 commits into
mainfrom
aaron/scores-runtime
Draft

Score runtime (D5): manifests, router, entitlements, stage guard, usage capture#76
aarontrowbridge wants to merge 20 commits into
mainfrom
aaron/scores-runtime

Conversation

@aarontrowbridge

Copy link
Copy Markdown
Member

Implements the score runtime (D5) from spec spec-20260703-025314-amicode-scores-front-of-chain (personal vault, reviewer-approved), plan plan-20260703-040654-amicode-score-runtime. Built on top of aaron/night-l0-pulse-designer (#75) in a separate worktree.

What this adds

  • Scores are content, not codescores/<id>/SCORE.md (YAML frontmatter + prose voice), validated + lint-gated (templates resolve, memory hooks resolve, lineage, entitlement registry, packaging). New user path = new directory, zero runtime changes.
  • Score #0 — the night build's 8-stage pulse-designer interview migrated to data. The hardcoded AGENTS.md section is untouched and serves as the fallback: score trouble can never brick the boot, and the night tests are unmodified.
  • Onset router — "What do you want to do today?" generated from installed × entitled scores (empty entitlements: = public; invalid/expired code → named error + public fallback; LocalEntitlementProvider stub implements the D3 interface).
  • "Data-defined, prompt-executed"prepareOpencodeProject compiles router + score over the injected AGENTS.md and drops score_manifest.json where the plugin looks (entitiesDir() — zero extension.ts changes).
  • Stage-order + gate guard in the amicode_* tools via a new dependency-free sibling opencode-plugin/score_guard.ts (entity dependencies block; conversational stages don't; no manifest → pure bookkeeping as before). Single-export invariant preserved (Bun probe: 1 export, 7 tools).
  • Usage captureusage.jsonl (session/stage/gate events) + funnel reconstruction; interview_state.json pins {score_id, score_version} so score revisions never disturb in-flight sessions.

Evidence

  • Unit suite 203/203 (baseline 128 + 75 new, incl. packaging asserted against a real .vsix).
  • Live e2e PASS (25 s, free tier): router options rendered → single-question cadence → LaTeX confirm → guard state on disk. Experiment note: experiment-20260703-scores-runtime-e2e (personal vault).

Coordination boundary

Nothing in the phased build moves. Shared files touched: src/opencode_config.ts (additive: scores splice + grant), opencode-plugin/amicode_tools.ts (additive: guard calls). AGENTS.md and all night tests untouched. Not in this PR (separate tracks per the spec): Altissimo GPU cloud (D1), Pulser/PasqalExecutor (D2), redemption service (D3), marketplace (D4), Layer-3 cards (D6), Pasqal score content.

🤖 Generated with Claude Code

aarontrowbridge and others added 20 commits July 3, 2026 02:28
Scoped to the pulse-designer persona (never hijacks the default build agent),
one-question-at-a-time, 8 stages PLATFORM→CALIBRATE, transmon fully wired /
Rydberg recorded-honestly, amicode_* tools as bookkeeping with bash+amico-run
still the launch mechanism. Tests: interview block + no-unknown-placeholder
assertion (only {{TEMPLATE_PATH}}/{{JULIA_PROJECT}} substituted).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…gin load / live turns)

Tier A green vs stock 1.17.3; B gates on the plugin file, C on creds
(none on this machine tonight — morning step: opencode auth login).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Four bookkeeping tools (pick_system / set_model / formulate / solve-record)
executed by opencode's embedded Bun runtime; entities as TOML under
~/.amico/runs/default/_entities ($AMICODE_ENTITIES_DIR override). Registration
via buildOpencodeConfigContent: plugin abs-path + pulse-designer agent block +
entities-dir permission grant (T8 probe: both mechanisms live at 1.17.3).
Plugin stays outside the extension bundle/tsconfig; load line on stderr
(debug-config stdout purity — regression-guarded). 99→122 tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Free anonymous provider (opencode/big-pickle) resolves without auth.json →
AMICODE_E2E_LIVE=1 forces the creds gate. Cadence assertion = stage-batching
check (multiple '?' inside one platform question is fine); transcript saved
to tmpdir for the experiment note.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Real-home mode now substitutes AGENTS.md via prepareOpencodeProject (stage 6
needs real template/julia paths). Keyword-routed answers, bounded turns,
run-dir poll. Result: 10 turns on the free model → all four amicode_* tools
fired (System→Formulation→Run stub) → authored solve.jl → amico-run launch →
F=0.9998977/60 iters. AMICODE_E2E_FULLCHAIN=1 gates it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
amicode_to_hardware (device_session stub; gate + checks PINNED by the
serializer so a stub can never claim an approval that didn't happen) and
amicode_calibrate (ILC stub, auto-refs device_session.toml). No device I/O —
explanations say so explicitly, mirroring AGENTS.md stage 8, which now names
both tools. 6 tools registered (verified via /experimental/tool/ids). 122→128
tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
'Who are you?' now answers 'I'm Amico — Amicode's pulse-design copilot'
(never 'opencode, an interactive CLI tool'), and a greeting/no-intent session
opener triggers the stage-1 PLATFORM question instead of a generic assistant
reply. Specific asks keep the skip rule.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Interview option-stages (platform, sim-vs-solve, problem/gate) now go through
amicode_ask(question, options[2-6]); the renderer draws buttons from the tool
part's input and a click sends the option text as the next user message.
Free-form values stay plain questions. 7 tools registered (runtime-verified).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e_manifest transport, scores-root grant, never-brick fallback
…s (score_guard sibling module, entitiesDir transport)
aarontrowbridge added a commit that referenced this pull request Jul 3, 2026
Interview-as-data lands on the L0 stack: SCORE.md manifests + loader/lint,
score #0 = the interview, onset router + entitlements, score_guard stage/gate
enforcement, usage funnel. AGENTS.md stays the never-brick fallback.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@aarontrowbridge

Copy link
Copy Markdown
Member Author

Merged into the night branch (d6f9719 on aaron/night-l0-pulse-designer, now in #75's diff) — 0 conflicts as predicted, suite 203/203, Bun single-export probe: 1 export / 7 tools. Inherited tasks done on the night branch: the 778e1bb ask-discipline prose + the anti-drift anchor-on-recorded-state rule are mirrored into scores/pulse-designer/SCORE.md (bumped to v2; prep tests made version-agnostic with a banner↔manifest cross-check, 7f28414). Also folded: the fixed-port feature found staged in the night tree (220794c, amicode.opencodePort default 43117). Merge order for main: #75 now carries everything; #76 can be closed into it or retargeted at Aaron's discretion.

🤖 Generated with Claude Code

jack-champagne pushed a commit that referenced this pull request Jul 3, 2026
…the per-solve "ask" nag (#79)

AGENTS.md instructs the agent to READ run artifacts (FINISHED/result.toml for
results, run.log for failure tracebacks) under the runs root — but the injected
permission.external_directory only granted the templates dir + /tmp/amicode-work.
opencode defaults external_directory to "ask", so every read-back fired a
permission prompt: one per solve, and repeatedly on failures (the 2026-07-03
live test hit this hard — four failing runs, agent in run.log each time).

Thread the resolved runsRoot (respects the amicode.runsRoot setting) into
buildOpencodeConfigContent and grant `${runsRoot}/**`. Still least-privilege:
scoped to the one additional root AGENTS.md actually sends the agent's file
tools into; amico-run's own subprocess writes never needed a grant.

Tests: unit (grant present + still path-scoped), real-opencode integration
(grant survives the 1.17.3 deep-merge alongside the user's global permission
keys). 93 pass, typecheck clean.

Note: Aaron's #75/#76 restructure the same permission block (adding entities/
scores grants — correctly); whichever lands second has a one-line rebase.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
jack-champagne added a commit that referenced this pull request Jul 4, 2026
The pre-solve formulation.toml emit could not run through the agent deploy
path: AGENTS.md copies solve_template.jl alone into a scratch dir and runs the
copy, so @__DIR__ was the scratch dir and include(emit_formulation.jl) resolved
to a file that was never copied — LoadError before solve!, on every run. CI
never executes the template, so it stayed green.

- Inline emit_formulation into solve_template.jl; delete the sibling helper.
  Sharing moves to a Julia package (AmicoRunDir.jl) when #75/#76 add a second
  template — the only share mechanism that survives the single-file copy.
- Tighten formulation.schema.json: per-family if/then — transmon requires and
  type-checks delta/levels/drive_max; formulation requires gate/T/N; Q/R
  optional; additionalProperties:true per family (unknown families lenient).
- Add template_deploy_contract.test.ts: reproduces the AGENTS.md single-file
  copy and asserts every include() resolves. Red on the bug, green inlined.

schema_version stays "1" (additive: no on-disk formulation.toml exists yet).
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