amico catalog (#111): B2 — real repertoire query + verified ingest verb - #119

Closed
aarontrowbridge wants to merge 1 commit into
b1-amico-cli-routerfrom
b2-catalog-verb
Closed

amico catalog (#111): B2 — real repertoire query + verified ingest verb#119
aarontrowbridge wants to merge 1 commit into
b1-amico-cli-routerfrom
b2-catalog-verb

Conversation

@aarontrowbridge

Copy link
Copy Markdown
Member

Closes#111. Stacks on #118 (B1 — the amico verb router); base branch is b1-amico-cli-router, not main. Review/merge #118 first.

What this does

Replaces B1's catalogstub with a working spine bookkeeping verb backed by the pulse repertoire~/.amico/vaults/armonissima/catalog/pulses/<id>/metadata.toml (the amico-catalog skill's Phase-0 schema). Both subcommands are deterministic filesystem work, callable via bash by either runtime, the harness, or cron/CI:

  • amico catalog query --platform <p> --kind <g> → the incumbent pulse metadata for (platform, gate) plus the ranked candidate list (fidelity desc; ties broken by shorter duration). This is the warm-start lookup the interview does before authoring a solve.
  • amico catalog ingest --platform <p> --kind <g> [--from-run <dir>] [--artifact <file.jld2>] [--fidelity <f>] [--agree true|false] … → the promotion path, gated on verification.agree (matching the existing semantics — a run is promotable only when the independent re-rollout agreed: verification.tomlagree = true). --from-run <dir> reads verification.toml (agree) + result.toml (fidelity) + defaults the artifact to <dir>/pulse.jld2; or pass --agree/--fidelity/--artifact explicitly. When gated open it promotes iff the candidate beats the incumbent (amico-catalog Version rule), writing a new {platform}-{kind}-v{N+1} entry (metadata.toml + copied pulse.jld2) with warm_start lineage back to the incumbent.

Exit codes follow the verb convention: agree ≠ trueblocked (64); verified but no beat → no-op (0); promoted → 0; usage/missing-artifact → 64.

Design

  • Pure core in repertoire.ts (loaders never throw — a corrupt/missing catalog degrades to empty, like src/catalog.ts's template/exemplar loaders); the verb body (arg parsing + writes) in catalog_verb.ts. verbs.ts wires catalog.run to it and marks it non-stub (a stub? flag so --help drops the [stub → …] tag for catalog only); vault/device/note stay B1 stubs. One impl backs both the CLI (amico.ts) and the mcp-serve facade (unchanged).
  • $AMICO_CATALOG_DIR overrides the pulses dir (tests point it at a temp catalog).

Flag-name note (S31 guard) — reviewer decision point

test/s31.test.ts bans the physics-knob double-dash flags (gate/pulse/system) anywhere in src/. So the gate discriminator is --kind (issue #111's acceptance surface; maps onto the repertoire's gate field), and the pulse-artifact path is --artifact rather than the issue's literal --pulse — a pulse-file path is not a physics knob (same category as --spec/--from-run), so it takes a non-colliding name. If you'd rather keep the literal --pulse, the alternative is an explicit, reviewed S31 carve-out amendment (the precedent mcp_serve.ts cites for spec C).

Tests

  • test/repertoire.test.ts-style pure-logic tests + query/ingest through the dist/amico.js bundle (test/catalog_verb.test.ts, 19 tests), mirroring amico.test.ts / subcommands.test.ts.
  • amico.test.ts's stub loop drops catalog (now real) and asserts it routes to query/ingest; vault/device/note still asserted as stubs.
  • amico-run: 141 passed (18 files). Extension fast suite: 435 passed, 3 skipped. Typecheck clean. No Julia-gated slow tests run (none apply to this slice).

Integration follow-up (out of scope here, per the slice)

This slice lands the CLI verb + tests only; it does not rewire the extension/interview. The remaining plugin→CLI migration: today the opencode interview has noamicode_catalog plugin tool (warm-start lookup is currently done ad hoc / not wired to the repertoire), and promotion lives in the extension's manual "Save pulse to catalog" quick-pick (run_controls.catalogPulsesDir). Issue #111's second acceptance box — "opencode interview does warm-start lookups via the CLI verb (bash)" — means wiring the interview's warm-start step to shell out to amico catalog query (and, optionally, routing promotion through amico catalog ingest so the verification.agree gate is enforced in one place). That belongs in the extension scores//plugin wiring, not amico-run, and should be its own slice/PR so this one stays reviewable.

Note: fork CI may be RED (pre-existing private-fork vendored-binary token issue), unrelated to this change.

🤖 Generated with Claude Code

Replace the B1 `catalog` stub with a working spine bookkeeping verb backed by
the pulse repertoire (~/.amico/vaults/armonissima/catalog/pulses/<id>/metadata.toml,
the amico-catalog skill's Phase-0 schema). Two subcommands, both deterministic
filesystem work callable via bash by either runtime, the harness, or cron/CI:
amico catalog query --platform <p> --kind <g>
→ the incumbent pulse metadata for (platform, gate) + the ranked candidate
list (fidelity desc; ties broken by shorter duration). This is the
warm-start lookup the interview does before authoring a solve.
amico catalog ingest --platform <p> --kind <g> [--from-run <dir>]
[--artifact <file.jld2>] [--fidelity <f>] [--agree …] …
→ the PROMOTION path, GATED on verification.agree (matching the existing
semantics — a run is promotable only when the independent re-rollout
agreed: verification.toml `agree = true`; --from-run reads it, or pass
--agree explicitly). When gated open it promotes iff the candidate beats
the incumbent (amico-catalog Version rule), writing a new
{platform}-{kind}-v{N+1} entry (metadata.toml + copied pulse.jld2) with
`warm_start` lineage back to the incumbent. agree≠true → blocked (64);
no beat → no-op (0); promoted → 0.
Design notes:
- Pure core in repertoire.ts (loaders never throw; a corrupt/missing catalog
degrades to empty, like src/catalog.ts's template/exemplar loaders); the verb
body (arg parsing + writes) in catalog_verb.ts. verbs.ts wires catalog.run to
it and marks it non-stub; vault/device/note stay B1 stubs. One impl backs both
the CLI (amico.ts) and the mcp-serve facade (unchanged).
- $AMICO_CATALOG_DIR overrides the pulses dir (tests point it at a temp catalog).
- FLAG NAMES honor the S31 guard (test/s31.test.ts bans the physics-knob
double-dash flags gate/pulse/system in src/): the gate discriminator is `--kind`
(issue #111's surface, maps to the `gate` field) and the pulse-artifact PATH is
`--artifact` (a file path, not a physics knob — same category as spec/from-run).
Tests: repertoire pure logic + query/ingest through the dist/amico.js bundle
(mirrors amico.test.ts / subcommands.test.ts); amico.test.ts's stub loop drops
catalog (now real) and asserts it routes to query/ingest. amico-run 141 green,
extension fast suite 435 green. Stacks on #118 (B1).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jack-champagne

Copy link
Copy Markdown
Member

Closing — this is already delivered. The work is on main; the PR was only ever paperwork left open by the stacked-branch flow.

b2-catalog-verb tip 0fd846d is a direct ancestor of main (d03d3c8), and git diff main...b2-catalog-verb is empty — nothing here is missing from main.

This PR targeted b1-amico-cli-router, which is itself already fully in main, so the diff shown on GitHub was never against a live base.

Branch preserved.

Sign up for freeto 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.

2 participants

@aarontrowbridge@jack-champagne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

amico catalog (#111): B2 — real repertoire query + verified ingest verb - #119

Closed
aarontrowbridge wants to merge 1 commit into
b1-amico-cli-routerfrom
b2-catalog-verb
Closed

amico catalog (#111): B2 — real repertoire query + verified ingest verb#119
aarontrowbridge wants to merge 1 commit into
b1-amico-cli-routerfrom
b2-catalog-verb

Conversation

@aarontrowbridge

Copy link
Copy Markdown
Member

Closes#111. Stacks on #118 (B1 — the amico verb router); base branch is b1-amico-cli-router, not main. Review/merge #118 first.

What this does

Replaces B1's catalogstub with a working spine bookkeeping verb backed by the pulse repertoire~/.amico/vaults/armonissima/catalog/pulses/<id>/metadata.toml (the amico-catalog skill's Phase-0 schema). Both subcommands are deterministic filesystem work, callable via bash by either runtime, the harness, or cron/CI:

  • amico catalog query --platform <p> --kind <g> → the incumbent pulse metadata for (platform, gate) plus the ranked candidate list (fidelity desc; ties broken by shorter duration). This is the warm-start lookup the interview does before authoring a solve.
  • amico catalog ingest --platform <p> --kind <g> [--from-run <dir>] [--artifact <file.jld2>] [--fidelity <f>] [--agree true|false] … → the promotion path, gated on verification.agree (matching the existing semantics — a run is promotable only when the independent re-rollout agreed: verification.tomlagree = true). --from-run <dir> reads verification.toml (agree) + result.toml (fidelity) + defaults the artifact to <dir>/pulse.jld2; or pass --agree/--fidelity/--artifact explicitly. When gated open it promotes iff the candidate beats the incumbent (amico-catalog Version rule), writing a new {platform}-{kind}-v{N+1} entry (metadata.toml + copied pulse.jld2) with warm_start lineage back to the incumbent.

Exit codes follow the verb convention: agree ≠ trueblocked (64); verified but no beat → no-op (0); promoted → 0; usage/missing-artifact → 64.

Design

  • Pure core in repertoire.ts (loaders never throw — a corrupt/missing catalog degrades to empty, like src/catalog.ts's template/exemplar loaders); the verb body (arg parsing + writes) in catalog_verb.ts. verbs.ts wires catalog.run to it and marks it non-stub (a stub? flag so --help drops the [stub → …] tag for catalog only); vault/device/note stay B1 stubs. One impl backs both the CLI (amico.ts) and the mcp-serve facade (unchanged).
  • $AMICO_CATALOG_DIR overrides the pulses dir (tests point it at a temp catalog).

Flag-name note (S31 guard) — reviewer decision point

test/s31.test.ts bans the physics-knob double-dash flags (gate/pulse/system) anywhere in src/. So the gate discriminator is --kind (issue #111's acceptance surface; maps onto the repertoire's gate field), and the pulse-artifact path is --artifact rather than the issue's literal --pulse — a pulse-file path is not a physics knob (same category as --spec/--from-run), so it takes a non-colliding name. If you'd rather keep the literal --pulse, the alternative is an explicit, reviewed S31 carve-out amendment (the precedent mcp_serve.ts cites for spec C).

Tests

  • test/repertoire.test.ts-style pure-logic tests + query/ingest through the dist/amico.js bundle (test/catalog_verb.test.ts, 19 tests), mirroring amico.test.ts / subcommands.test.ts.
  • amico.test.ts's stub loop drops catalog (now real) and asserts it routes to query/ingest; vault/device/note still asserted as stubs.
  • amico-run: 141 passed (18 files). Extension fast suite: 435 passed, 3 skipped. Typecheck clean. No Julia-gated slow tests run (none apply to this slice).

Integration follow-up (out of scope here, per the slice)

This slice lands the CLI verb + tests only; it does not rewire the extension/interview. The remaining plugin→CLI migration: today the opencode interview has noamicode_catalog plugin tool (warm-start lookup is currently done ad hoc / not wired to the repertoire), and promotion lives in the extension's manual "Save pulse to catalog" quick-pick (run_controls.catalogPulsesDir). Issue #111's second acceptance box — "opencode interview does warm-start lookups via the CLI verb (bash)" — means wiring the interview's warm-start step to shell out to amico catalog query (and, optionally, routing promotion through amico catalog ingest so the verification.agree gate is enforced in one place). That belongs in the extension scores//plugin wiring, not amico-run, and should be its own slice/PR so this one stays reviewable.

Note: fork CI may be RED (pre-existing private-fork vendored-binary token issue), unrelated to this change.

🤖 Generated with Claude Code

Replace the B1 `catalog` stub with a working spine bookkeeping verb backed by
the pulse repertoire (~/.amico/vaults/armonissima/catalog/pulses/<id>/metadata.toml,
the amico-catalog skill's Phase-0 schema). Two subcommands, both deterministic
filesystem work callable via bash by either runtime, the harness, or cron/CI:
amico catalog query --platform <p> --kind <g>
→ the incumbent pulse metadata for (platform, gate) + the ranked candidate
list (fidelity desc; ties broken by shorter duration). This is the
warm-start lookup the interview does before authoring a solve.
amico catalog ingest --platform <p> --kind <g> [--from-run <dir>]
[--artifact <file.jld2>] [--fidelity <f>] [--agree …] …
→ the PROMOTION path, GATED on verification.agree (matching the existing
semantics — a run is promotable only when the independent re-rollout
agreed: verification.toml `agree = true`; --from-run reads it, or pass
--agree explicitly). When gated open it promotes iff the candidate beats
the incumbent (amico-catalog Version rule), writing a new
{platform}-{kind}-v{N+1} entry (metadata.toml + copied pulse.jld2) with
`warm_start` lineage back to the incumbent. agree≠true → blocked (64);
no beat → no-op (0); promoted → 0.
Design notes:
- Pure core in repertoire.ts (loaders never throw; a corrupt/missing catalog
degrades to empty, like src/catalog.ts's template/exemplar loaders); the verb
body (arg parsing + writes) in catalog_verb.ts. verbs.ts wires catalog.run to
it and marks it non-stub; vault/device/note stay B1 stubs. One impl backs both
the CLI (amico.ts) and the mcp-serve facade (unchanged).
- $AMICO_CATALOG_DIR overrides the pulses dir (tests point it at a temp catalog).
- FLAG NAMES honor the S31 guard (test/s31.test.ts bans the physics-knob
double-dash flags gate/pulse/system in src/): the gate discriminator is `--kind`
(issue #111's surface, maps to the `gate` field) and the pulse-artifact PATH is
`--artifact` (a file path, not a physics knob — same category as spec/from-run).
Tests: repertoire pure logic + query/ingest through the dist/amico.js bundle
(mirrors amico.test.ts / subcommands.test.ts); amico.test.ts's stub loop drops
catalog (now real) and asserts it routes to query/ingest. amico-run 141 green,
extension fast suite 435 green. Stacks on #118 (B1).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jack-champagne

Copy link
Copy Markdown
Member

Closing — this is already delivered. The work is on main; the PR was only ever paperwork left open by the stacked-branch flow.

b2-catalog-verb tip 0fd846d is a direct ancestor of main (d03d3c8), and git diff main...b2-catalog-verb is empty — nothing here is missing from main.

This PR targeted b1-amico-cli-router, which is itself already fully in main, so the diff shown on GitHub was never against a live base.

Branch preserved.

Sign up for freeto 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.

2 participants

@aarontrowbridge@jack-champagne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

amico catalog (#111): B2 — real repertoire query + verified ingest verb - #119

Closed
aarontrowbridge wants to merge 1 commit into
b1-amico-cli-routerfrom
b2-catalog-verb
Closed

amico catalog (#111): B2 — real repertoire query + verified ingest verb#119
aarontrowbridge wants to merge 1 commit into
b1-amico-cli-routerfrom
b2-catalog-verb

Conversation

@aarontrowbridge

Copy link
Copy Markdown
Member

Closes#111. Stacks on #118 (B1 — the amico verb router); base branch is b1-amico-cli-router, not main. Review/merge #118 first.

What this does

Replaces B1's catalogstub with a working spine bookkeeping verb backed by the pulse repertoire~/.amico/vaults/armonissima/catalog/pulses/<id>/metadata.toml (the amico-catalog skill's Phase-0 schema). Both subcommands are deterministic filesystem work, callable via bash by either runtime, the harness, or cron/CI:

  • amico catalog query --platform <p> --kind <g> → the incumbent pulse metadata for (platform, gate) plus the ranked candidate list (fidelity desc; ties broken by shorter duration). This is the warm-start lookup the interview does before authoring a solve.
  • amico catalog ingest --platform <p> --kind <g> [--from-run <dir>] [--artifact <file.jld2>] [--fidelity <f>] [--agree true|false] … → the promotion path, gated on verification.agree (matching the existing semantics — a run is promotable only when the independent re-rollout agreed: verification.tomlagree = true). --from-run <dir> reads verification.toml (agree) + result.toml (fidelity) + defaults the artifact to <dir>/pulse.jld2; or pass --agree/--fidelity/--artifact explicitly. When gated open it promotes iff the candidate beats the incumbent (amico-catalog Version rule), writing a new {platform}-{kind}-v{N+1} entry (metadata.toml + copied pulse.jld2) with warm_start lineage back to the incumbent.

Exit codes follow the verb convention: agree ≠ trueblocked (64); verified but no beat → no-op (0); promoted → 0; usage/missing-artifact → 64.

Design

  • Pure core in repertoire.ts (loaders never throw — a corrupt/missing catalog degrades to empty, like src/catalog.ts's template/exemplar loaders); the verb body (arg parsing + writes) in catalog_verb.ts. verbs.ts wires catalog.run to it and marks it non-stub (a stub? flag so --help drops the [stub → …] tag for catalog only); vault/device/note stay B1 stubs. One impl backs both the CLI (amico.ts) and the mcp-serve facade (unchanged).
  • $AMICO_CATALOG_DIR overrides the pulses dir (tests point it at a temp catalog).

Flag-name note (S31 guard) — reviewer decision point

test/s31.test.ts bans the physics-knob double-dash flags (gate/pulse/system) anywhere in src/. So the gate discriminator is --kind (issue #111's acceptance surface; maps onto the repertoire's gate field), and the pulse-artifact path is --artifact rather than the issue's literal --pulse — a pulse-file path is not a physics knob (same category as --spec/--from-run), so it takes a non-colliding name. If you'd rather keep the literal --pulse, the alternative is an explicit, reviewed S31 carve-out amendment (the precedent mcp_serve.ts cites for spec C).

Tests

  • test/repertoire.test.ts-style pure-logic tests + query/ingest through the dist/amico.js bundle (test/catalog_verb.test.ts, 19 tests), mirroring amico.test.ts / subcommands.test.ts.
  • amico.test.ts's stub loop drops catalog (now real) and asserts it routes to query/ingest; vault/device/note still asserted as stubs.
  • amico-run: 141 passed (18 files). Extension fast suite: 435 passed, 3 skipped. Typecheck clean. No Julia-gated slow tests run (none apply to this slice).

Integration follow-up (out of scope here, per the slice)

This slice lands the CLI verb + tests only; it does not rewire the extension/interview. The remaining plugin→CLI migration: today the opencode interview has noamicode_catalog plugin tool (warm-start lookup is currently done ad hoc / not wired to the repertoire), and promotion lives in the extension's manual "Save pulse to catalog" quick-pick (run_controls.catalogPulsesDir). Issue #111's second acceptance box — "opencode interview does warm-start lookups via the CLI verb (bash)" — means wiring the interview's warm-start step to shell out to amico catalog query (and, optionally, routing promotion through amico catalog ingest so the verification.agree gate is enforced in one place). That belongs in the extension scores//plugin wiring, not amico-run, and should be its own slice/PR so this one stays reviewable.

Note: fork CI may be RED (pre-existing private-fork vendored-binary token issue), unrelated to this change.

🤖 Generated with Claude Code

Replace the B1 `catalog` stub with a working spine bookkeeping verb backed by
the pulse repertoire (~/.amico/vaults/armonissima/catalog/pulses/<id>/metadata.toml,
the amico-catalog skill's Phase-0 schema). Two subcommands, both deterministic
filesystem work callable via bash by either runtime, the harness, or cron/CI:
amico catalog query --platform <p> --kind <g>
→ the incumbent pulse metadata for (platform, gate) + the ranked candidate
list (fidelity desc; ties broken by shorter duration). This is the
warm-start lookup the interview does before authoring a solve.
amico catalog ingest --platform <p> --kind <g> [--from-run <dir>]
[--artifact <file.jld2>] [--fidelity <f>] [--agree …] …
→ the PROMOTION path, GATED on verification.agree (matching the existing
semantics — a run is promotable only when the independent re-rollout
agreed: verification.toml `agree = true`; --from-run reads it, or pass
--agree explicitly). When gated open it promotes iff the candidate beats
the incumbent (amico-catalog Version rule), writing a new
{platform}-{kind}-v{N+1} entry (metadata.toml + copied pulse.jld2) with
`warm_start` lineage back to the incumbent. agree≠true → blocked (64);
no beat → no-op (0); promoted → 0.
Design notes:
- Pure core in repertoire.ts (loaders never throw; a corrupt/missing catalog
degrades to empty, like src/catalog.ts's template/exemplar loaders); the verb
body (arg parsing + writes) in catalog_verb.ts. verbs.ts wires catalog.run to
it and marks it non-stub; vault/device/note stay B1 stubs. One impl backs both
the CLI (amico.ts) and the mcp-serve facade (unchanged).
- $AMICO_CATALOG_DIR overrides the pulses dir (tests point it at a temp catalog).
- FLAG NAMES honor the S31 guard (test/s31.test.ts bans the physics-knob
double-dash flags gate/pulse/system in src/): the gate discriminator is `--kind`
(issue #111's surface, maps to the `gate` field) and the pulse-artifact PATH is
`--artifact` (a file path, not a physics knob — same category as spec/from-run).
Tests: repertoire pure logic + query/ingest through the dist/amico.js bundle
(mirrors amico.test.ts / subcommands.test.ts); amico.test.ts's stub loop drops
catalog (now real) and asserts it routes to query/ingest. amico-run 141 green,
extension fast suite 435 green. Stacks on #118 (B1).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jack-champagne

Copy link
Copy Markdown
Member

Closing — this is already delivered. The work is on main; the PR was only ever paperwork left open by the stacked-branch flow.

b2-catalog-verb tip 0fd846d is a direct ancestor of main (d03d3c8), and git diff main...b2-catalog-verb is empty — nothing here is missing from main.

This PR targeted b1-amico-cli-router, which is itself already fully in main, so the diff shown on GitHub was never against a live base.

Branch preserved.

Sign up for freeto 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.

2 participants

@aarontrowbridge@jack-champagne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

amico catalog (#111): B2 — real repertoire query + verified ingest verb - #119

Closed
aarontrowbridge wants to merge 1 commit into
b1-amico-cli-routerfrom
b2-catalog-verb
Closed

amico catalog (#111): B2 — real repertoire query + verified ingest verb#119
aarontrowbridge wants to merge 1 commit into
b1-amico-cli-routerfrom
b2-catalog-verb

Conversation

@aarontrowbridge

Copy link
Copy Markdown
Member

Closes#111. Stacks on #118 (B1 — the amico verb router); base branch is b1-amico-cli-router, not main. Review/merge #118 first.

What this does

Replaces B1's catalogstub with a working spine bookkeeping verb backed by the pulse repertoire~/.amico/vaults/armonissima/catalog/pulses/<id>/metadata.toml (the amico-catalog skill's Phase-0 schema). Both subcommands are deterministic filesystem work, callable via bash by either runtime, the harness, or cron/CI:

  • amico catalog query --platform <p> --kind <g> → the incumbent pulse metadata for (platform, gate) plus the ranked candidate list (fidelity desc; ties broken by shorter duration). This is the warm-start lookup the interview does before authoring a solve.
  • amico catalog ingest --platform <p> --kind <g> [--from-run <dir>] [--artifact <file.jld2>] [--fidelity <f>] [--agree true|false] … → the promotion path, gated on verification.agree (matching the existing semantics — a run is promotable only when the independent re-rollout agreed: verification.tomlagree = true). --from-run <dir> reads verification.toml (agree) + result.toml (fidelity) + defaults the artifact to <dir>/pulse.jld2; or pass --agree/--fidelity/--artifact explicitly. When gated open it promotes iff the candidate beats the incumbent (amico-catalog Version rule), writing a new {platform}-{kind}-v{N+1} entry (metadata.toml + copied pulse.jld2) with warm_start lineage back to the incumbent.

Exit codes follow the verb convention: agree ≠ trueblocked (64); verified but no beat → no-op (0); promoted → 0; usage/missing-artifact → 64.

Design

  • Pure core in repertoire.ts (loaders never throw — a corrupt/missing catalog degrades to empty, like src/catalog.ts's template/exemplar loaders); the verb body (arg parsing + writes) in catalog_verb.ts. verbs.ts wires catalog.run to it and marks it non-stub (a stub? flag so --help drops the [stub → …] tag for catalog only); vault/device/note stay B1 stubs. One impl backs both the CLI (amico.ts) and the mcp-serve facade (unchanged).
  • $AMICO_CATALOG_DIR overrides the pulses dir (tests point it at a temp catalog).

Flag-name note (S31 guard) — reviewer decision point

test/s31.test.ts bans the physics-knob double-dash flags (gate/pulse/system) anywhere in src/. So the gate discriminator is --kind (issue #111's acceptance surface; maps onto the repertoire's gate field), and the pulse-artifact path is --artifact rather than the issue's literal --pulse — a pulse-file path is not a physics knob (same category as --spec/--from-run), so it takes a non-colliding name. If you'd rather keep the literal --pulse, the alternative is an explicit, reviewed S31 carve-out amendment (the precedent mcp_serve.ts cites for spec C).

Tests

  • test/repertoire.test.ts-style pure-logic tests + query/ingest through the dist/amico.js bundle (test/catalog_verb.test.ts, 19 tests), mirroring amico.test.ts / subcommands.test.ts.
  • amico.test.ts's stub loop drops catalog (now real) and asserts it routes to query/ingest; vault/device/note still asserted as stubs.
  • amico-run: 141 passed (18 files). Extension fast suite: 435 passed, 3 skipped. Typecheck clean. No Julia-gated slow tests run (none apply to this slice).

Integration follow-up (out of scope here, per the slice)

This slice lands the CLI verb + tests only; it does not rewire the extension/interview. The remaining plugin→CLI migration: today the opencode interview has noamicode_catalog plugin tool (warm-start lookup is currently done ad hoc / not wired to the repertoire), and promotion lives in the extension's manual "Save pulse to catalog" quick-pick (run_controls.catalogPulsesDir). Issue #111's second acceptance box — "opencode interview does warm-start lookups via the CLI verb (bash)" — means wiring the interview's warm-start step to shell out to amico catalog query (and, optionally, routing promotion through amico catalog ingest so the verification.agree gate is enforced in one place). That belongs in the extension scores//plugin wiring, not amico-run, and should be its own slice/PR so this one stays reviewable.

Note: fork CI may be RED (pre-existing private-fork vendored-binary token issue), unrelated to this change.

🤖 Generated with Claude Code

Replace the B1 `catalog` stub with a working spine bookkeeping verb backed by
the pulse repertoire (~/.amico/vaults/armonissima/catalog/pulses/<id>/metadata.toml,
the amico-catalog skill's Phase-0 schema). Two subcommands, both deterministic
filesystem work callable via bash by either runtime, the harness, or cron/CI:
amico catalog query --platform <p> --kind <g>
→ the incumbent pulse metadata for (platform, gate) + the ranked candidate
list (fidelity desc; ties broken by shorter duration). This is the
warm-start lookup the interview does before authoring a solve.
amico catalog ingest --platform <p> --kind <g> [--from-run <dir>]
[--artifact <file.jld2>] [--fidelity <f>] [--agree …] …
→ the PROMOTION path, GATED on verification.agree (matching the existing
semantics — a run is promotable only when the independent re-rollout
agreed: verification.toml `agree = true`; --from-run reads it, or pass
--agree explicitly). When gated open it promotes iff the candidate beats
the incumbent (amico-catalog Version rule), writing a new
{platform}-{kind}-v{N+1} entry (metadata.toml + copied pulse.jld2) with
`warm_start` lineage back to the incumbent. agree≠true → blocked (64);
no beat → no-op (0); promoted → 0.
Design notes:
- Pure core in repertoire.ts (loaders never throw; a corrupt/missing catalog
degrades to empty, like src/catalog.ts's template/exemplar loaders); the verb
body (arg parsing + writes) in catalog_verb.ts. verbs.ts wires catalog.run to
it and marks it non-stub; vault/device/note stay B1 stubs. One impl backs both
the CLI (amico.ts) and the mcp-serve facade (unchanged).
- $AMICO_CATALOG_DIR overrides the pulses dir (tests point it at a temp catalog).
- FLAG NAMES honor the S31 guard (test/s31.test.ts bans the physics-knob
double-dash flags gate/pulse/system in src/): the gate discriminator is `--kind`
(issue #111's surface, maps to the `gate` field) and the pulse-artifact PATH is
`--artifact` (a file path, not a physics knob — same category as spec/from-run).
Tests: repertoire pure logic + query/ingest through the dist/amico.js bundle
(mirrors amico.test.ts / subcommands.test.ts); amico.test.ts's stub loop drops
catalog (now real) and asserts it routes to query/ingest. amico-run 141 green,
extension fast suite 435 green. Stacks on #118 (B1).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jack-champagne

Copy link
Copy Markdown
Member

Closing — this is already delivered. The work is on main; the PR was only ever paperwork left open by the stacked-branch flow.

b2-catalog-verb tip 0fd846d is a direct ancestor of main (d03d3c8), and git diff main...b2-catalog-verb is empty — nothing here is missing from main.

This PR targeted b1-amico-cli-router, which is itself already fully in main, so the diff shown on GitHub was never against a live base.

Branch preserved.

Sign up for freeto 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.

2 participants

@aarontrowbridge@jack-champagne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

amico catalog (#111): B2 — real repertoire query + verified ingest verb - #119

Closed
aarontrowbridge wants to merge 1 commit into
b1-amico-cli-routerfrom
b2-catalog-verb
Closed

amico catalog (#111): B2 — real repertoire query + verified ingest verb#119
aarontrowbridge wants to merge 1 commit into
b1-amico-cli-routerfrom
b2-catalog-verb

Conversation

@aarontrowbridge

Copy link
Copy Markdown
Member

Closes#111. Stacks on #118 (B1 — the amico verb router); base branch is b1-amico-cli-router, not main. Review/merge #118 first.

What this does

Replaces B1's catalogstub with a working spine bookkeeping verb backed by the pulse repertoire~/.amico/vaults/armonissima/catalog/pulses/<id>/metadata.toml (the amico-catalog skill's Phase-0 schema). Both subcommands are deterministic filesystem work, callable via bash by either runtime, the harness, or cron/CI:

  • amico catalog query --platform <p> --kind <g> → the incumbent pulse metadata for (platform, gate) plus the ranked candidate list (fidelity desc; ties broken by shorter duration). This is the warm-start lookup the interview does before authoring a solve.
  • amico catalog ingest --platform <p> --kind <g> [--from-run <dir>] [--artifact <file.jld2>] [--fidelity <f>] [--agree true|false] … → the promotion path, gated on verification.agree (matching the existing semantics — a run is promotable only when the independent re-rollout agreed: verification.tomlagree = true). --from-run <dir> reads verification.toml (agree) + result.toml (fidelity) + defaults the artifact to <dir>/pulse.jld2; or pass --agree/--fidelity/--artifact explicitly. When gated open it promotes iff the candidate beats the incumbent (amico-catalog Version rule), writing a new {platform}-{kind}-v{N+1} entry (metadata.toml + copied pulse.jld2) with warm_start lineage back to the incumbent.

Exit codes follow the verb convention: agree ≠ trueblocked (64); verified but no beat → no-op (0); promoted → 0; usage/missing-artifact → 64.

Design

  • Pure core in repertoire.ts (loaders never throw — a corrupt/missing catalog degrades to empty, like src/catalog.ts's template/exemplar loaders); the verb body (arg parsing + writes) in catalog_verb.ts. verbs.ts wires catalog.run to it and marks it non-stub (a stub? flag so --help drops the [stub → …] tag for catalog only); vault/device/note stay B1 stubs. One impl backs both the CLI (amico.ts) and the mcp-serve facade (unchanged).
  • $AMICO_CATALOG_DIR overrides the pulses dir (tests point it at a temp catalog).

Flag-name note (S31 guard) — reviewer decision point

test/s31.test.ts bans the physics-knob double-dash flags (gate/pulse/system) anywhere in src/. So the gate discriminator is --kind (issue #111's acceptance surface; maps onto the repertoire's gate field), and the pulse-artifact path is --artifact rather than the issue's literal --pulse — a pulse-file path is not a physics knob (same category as --spec/--from-run), so it takes a non-colliding name. If you'd rather keep the literal --pulse, the alternative is an explicit, reviewed S31 carve-out amendment (the precedent mcp_serve.ts cites for spec C).

Tests

  • test/repertoire.test.ts-style pure-logic tests + query/ingest through the dist/amico.js bundle (test/catalog_verb.test.ts, 19 tests), mirroring amico.test.ts / subcommands.test.ts.
  • amico.test.ts's stub loop drops catalog (now real) and asserts it routes to query/ingest; vault/device/note still asserted as stubs.
  • amico-run: 141 passed (18 files). Extension fast suite: 435 passed, 3 skipped. Typecheck clean. No Julia-gated slow tests run (none apply to this slice).

Integration follow-up (out of scope here, per the slice)

This slice lands the CLI verb + tests only; it does not rewire the extension/interview. The remaining plugin→CLI migration: today the opencode interview has noamicode_catalog plugin tool (warm-start lookup is currently done ad hoc / not wired to the repertoire), and promotion lives in the extension's manual "Save pulse to catalog" quick-pick (run_controls.catalogPulsesDir). Issue #111's second acceptance box — "opencode interview does warm-start lookups via the CLI verb (bash)" — means wiring the interview's warm-start step to shell out to amico catalog query (and, optionally, routing promotion through amico catalog ingest so the verification.agree gate is enforced in one place). That belongs in the extension scores//plugin wiring, not amico-run, and should be its own slice/PR so this one stays reviewable.

Note: fork CI may be RED (pre-existing private-fork vendored-binary token issue), unrelated to this change.

🤖 Generated with Claude Code

Replace the B1 `catalog` stub with a working spine bookkeeping verb backed by
the pulse repertoire (~/.amico/vaults/armonissima/catalog/pulses/<id>/metadata.toml,
the amico-catalog skill's Phase-0 schema). Two subcommands, both deterministic
filesystem work callable via bash by either runtime, the harness, or cron/CI:
amico catalog query --platform <p> --kind <g>
→ the incumbent pulse metadata for (platform, gate) + the ranked candidate
list (fidelity desc; ties broken by shorter duration). This is the
warm-start lookup the interview does before authoring a solve.
amico catalog ingest --platform <p> --kind <g> [--from-run <dir>]
[--artifact <file.jld2>] [--fidelity <f>] [--agree …] …
→ the PROMOTION path, GATED on verification.agree (matching the existing
semantics — a run is promotable only when the independent re-rollout
agreed: verification.toml `agree = true`; --from-run reads it, or pass
--agree explicitly). When gated open it promotes iff the candidate beats
the incumbent (amico-catalog Version rule), writing a new
{platform}-{kind}-v{N+1} entry (metadata.toml + copied pulse.jld2) with
`warm_start` lineage back to the incumbent. agree≠true → blocked (64);
no beat → no-op (0); promoted → 0.
Design notes:
- Pure core in repertoire.ts (loaders never throw; a corrupt/missing catalog
degrades to empty, like src/catalog.ts's template/exemplar loaders); the verb
body (arg parsing + writes) in catalog_verb.ts. verbs.ts wires catalog.run to
it and marks it non-stub; vault/device/note stay B1 stubs. One impl backs both
the CLI (amico.ts) and the mcp-serve facade (unchanged).
- $AMICO_CATALOG_DIR overrides the pulses dir (tests point it at a temp catalog).
- FLAG NAMES honor the S31 guard (test/s31.test.ts bans the physics-knob
double-dash flags gate/pulse/system in src/): the gate discriminator is `--kind`
(issue #111's surface, maps to the `gate` field) and the pulse-artifact PATH is
`--artifact` (a file path, not a physics knob — same category as spec/from-run).
Tests: repertoire pure logic + query/ingest through the dist/amico.js bundle
(mirrors amico.test.ts / subcommands.test.ts); amico.test.ts's stub loop drops
catalog (now real) and asserts it routes to query/ingest. amico-run 141 green,
extension fast suite 435 green. Stacks on #118 (B1).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jack-champagne

Copy link
Copy Markdown
Member

Closing — this is already delivered. The work is on main; the PR was only ever paperwork left open by the stacked-branch flow.

b2-catalog-verb tip 0fd846d is a direct ancestor of main (d03d3c8), and git diff main...b2-catalog-verb is empty — nothing here is missing from main.

This PR targeted b1-amico-cli-router, which is itself already fully in main, so the diff shown on GitHub was never against a live base.

Branch preserved.

Sign up for freeto 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.

2 participants

@aarontrowbridge@jack-champagne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

amico catalog (#111): B2 — real repertoire query + verified ingest verb - #119

Closed
aarontrowbridge wants to merge 1 commit into
b1-amico-cli-routerfrom
b2-catalog-verb
Closed

amico catalog (#111): B2 — real repertoire query + verified ingest verb#119
aarontrowbridge wants to merge 1 commit into
b1-amico-cli-routerfrom
b2-catalog-verb

Conversation

@aarontrowbridge

Copy link
Copy Markdown
Member

Closes#111. Stacks on #118 (B1 — the amico verb router); base branch is b1-amico-cli-router, not main. Review/merge #118 first.

What this does

Replaces B1's catalogstub with a working spine bookkeeping verb backed by the pulse repertoire~/.amico/vaults/armonissima/catalog/pulses/<id>/metadata.toml (the amico-catalog skill's Phase-0 schema). Both subcommands are deterministic filesystem work, callable via bash by either runtime, the harness, or cron/CI:

  • amico catalog query --platform <p> --kind <g> → the incumbent pulse metadata for (platform, gate) plus the ranked candidate list (fidelity desc; ties broken by shorter duration). This is the warm-start lookup the interview does before authoring a solve.
  • amico catalog ingest --platform <p> --kind <g> [--from-run <dir>] [--artifact <file.jld2>] [--fidelity <f>] [--agree true|false] … → the promotion path, gated on verification.agree (matching the existing semantics — a run is promotable only when the independent re-rollout agreed: verification.tomlagree = true). --from-run <dir> reads verification.toml (agree) + result.toml (fidelity) + defaults the artifact to <dir>/pulse.jld2; or pass --agree/--fidelity/--artifact explicitly. When gated open it promotes iff the candidate beats the incumbent (amico-catalog Version rule), writing a new {platform}-{kind}-v{N+1} entry (metadata.toml + copied pulse.jld2) with warm_start lineage back to the incumbent.

Exit codes follow the verb convention: agree ≠ trueblocked (64); verified but no beat → no-op (0); promoted → 0; usage/missing-artifact → 64.

Design

  • Pure core in repertoire.ts (loaders never throw — a corrupt/missing catalog degrades to empty, like src/catalog.ts's template/exemplar loaders); the verb body (arg parsing + writes) in catalog_verb.ts. verbs.ts wires catalog.run to it and marks it non-stub (a stub? flag so --help drops the [stub → …] tag for catalog only); vault/device/note stay B1 stubs. One impl backs both the CLI (amico.ts) and the mcp-serve facade (unchanged).
  • $AMICO_CATALOG_DIR overrides the pulses dir (tests point it at a temp catalog).

Flag-name note (S31 guard) — reviewer decision point

test/s31.test.ts bans the physics-knob double-dash flags (gate/pulse/system) anywhere in src/. So the gate discriminator is --kind (issue #111's acceptance surface; maps onto the repertoire's gate field), and the pulse-artifact path is --artifact rather than the issue's literal --pulse — a pulse-file path is not a physics knob (same category as --spec/--from-run), so it takes a non-colliding name. If you'd rather keep the literal --pulse, the alternative is an explicit, reviewed S31 carve-out amendment (the precedent mcp_serve.ts cites for spec C).

Tests

  • test/repertoire.test.ts-style pure-logic tests + query/ingest through the dist/amico.js bundle (test/catalog_verb.test.ts, 19 tests), mirroring amico.test.ts / subcommands.test.ts.
  • amico.test.ts's stub loop drops catalog (now real) and asserts it routes to query/ingest; vault/device/note still asserted as stubs.
  • amico-run: 141 passed (18 files). Extension fast suite: 435 passed, 3 skipped. Typecheck clean. No Julia-gated slow tests run (none apply to this slice).

Integration follow-up (out of scope here, per the slice)

This slice lands the CLI verb + tests only; it does not rewire the extension/interview. The remaining plugin→CLI migration: today the opencode interview has noamicode_catalog plugin tool (warm-start lookup is currently done ad hoc / not wired to the repertoire), and promotion lives in the extension's manual "Save pulse to catalog" quick-pick (run_controls.catalogPulsesDir). Issue #111's second acceptance box — "opencode interview does warm-start lookups via the CLI verb (bash)" — means wiring the interview's warm-start step to shell out to amico catalog query (and, optionally, routing promotion through amico catalog ingest so the verification.agree gate is enforced in one place). That belongs in the extension scores//plugin wiring, not amico-run, and should be its own slice/PR so this one stays reviewable.

Note: fork CI may be RED (pre-existing private-fork vendored-binary token issue), unrelated to this change.

🤖 Generated with Claude Code

Replace the B1 `catalog` stub with a working spine bookkeeping verb backed by
the pulse repertoire (~/.amico/vaults/armonissima/catalog/pulses/<id>/metadata.toml,
the amico-catalog skill's Phase-0 schema). Two subcommands, both deterministic
filesystem work callable via bash by either runtime, the harness, or cron/CI:
amico catalog query --platform <p> --kind <g>
→ the incumbent pulse metadata for (platform, gate) + the ranked candidate
list (fidelity desc; ties broken by shorter duration). This is the
warm-start lookup the interview does before authoring a solve.
amico catalog ingest --platform <p> --kind <g> [--from-run <dir>]
[--artifact <file.jld2>] [--fidelity <f>] [--agree …] …
→ the PROMOTION path, GATED on verification.agree (matching the existing
semantics — a run is promotable only when the independent re-rollout
agreed: verification.toml `agree = true`; --from-run reads it, or pass
--agree explicitly). When gated open it promotes iff the candidate beats
the incumbent (amico-catalog Version rule), writing a new
{platform}-{kind}-v{N+1} entry (metadata.toml + copied pulse.jld2) with
`warm_start` lineage back to the incumbent. agree≠true → blocked (64);
no beat → no-op (0); promoted → 0.
Design notes:
- Pure core in repertoire.ts (loaders never throw; a corrupt/missing catalog
degrades to empty, like src/catalog.ts's template/exemplar loaders); the verb
body (arg parsing + writes) in catalog_verb.ts. verbs.ts wires catalog.run to
it and marks it non-stub; vault/device/note stay B1 stubs. One impl backs both
the CLI (amico.ts) and the mcp-serve facade (unchanged).
- $AMICO_CATALOG_DIR overrides the pulses dir (tests point it at a temp catalog).
- FLAG NAMES honor the S31 guard (test/s31.test.ts bans the physics-knob
double-dash flags gate/pulse/system in src/): the gate discriminator is `--kind`
(issue #111's surface, maps to the `gate` field) and the pulse-artifact PATH is
`--artifact` (a file path, not a physics knob — same category as spec/from-run).
Tests: repertoire pure logic + query/ingest through the dist/amico.js bundle
(mirrors amico.test.ts / subcommands.test.ts); amico.test.ts's stub loop drops
catalog (now real) and asserts it routes to query/ingest. amico-run 141 green,
extension fast suite 435 green. Stacks on #118 (B1).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jack-champagne

Copy link
Copy Markdown
Member

Closing — this is already delivered. The work is on main; the PR was only ever paperwork left open by the stacked-branch flow.

b2-catalog-verb tip 0fd846d is a direct ancestor of main (d03d3c8), and git diff main...b2-catalog-verb is empty — nothing here is missing from main.

This PR targeted b1-amico-cli-router, which is itself already fully in main, so the diff shown on GitHub was never against a live base.

Branch preserved.

Sign up for freeto 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.

2 participants

@aarontrowbridge@jack-champagne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

amico catalog (#111): B2 — real repertoire query + verified ingest verb - #119

Closed
aarontrowbridge wants to merge 1 commit into
b1-amico-cli-routerfrom
b2-catalog-verb
Closed

amico catalog (#111): B2 — real repertoire query + verified ingest verb#119
aarontrowbridge wants to merge 1 commit into
b1-amico-cli-routerfrom
b2-catalog-verb

Conversation

@aarontrowbridge

Copy link
Copy Markdown
Member

Closes#111. Stacks on #118 (B1 — the amico verb router); base branch is b1-amico-cli-router, not main. Review/merge #118 first.

What this does

Replaces B1's catalogstub with a working spine bookkeeping verb backed by the pulse repertoire~/.amico/vaults/armonissima/catalog/pulses/<id>/metadata.toml (the amico-catalog skill's Phase-0 schema). Both subcommands are deterministic filesystem work, callable via bash by either runtime, the harness, or cron/CI:

  • amico catalog query --platform <p> --kind <g> → the incumbent pulse metadata for (platform, gate) plus the ranked candidate list (fidelity desc; ties broken by shorter duration). This is the warm-start lookup the interview does before authoring a solve.
  • amico catalog ingest --platform <p> --kind <g> [--from-run <dir>] [--artifact <file.jld2>] [--fidelity <f>] [--agree true|false] … → the promotion path, gated on verification.agree (matching the existing semantics — a run is promotable only when the independent re-rollout agreed: verification.tomlagree = true). --from-run <dir> reads verification.toml (agree) + result.toml (fidelity) + defaults the artifact to <dir>/pulse.jld2; or pass --agree/--fidelity/--artifact explicitly. When gated open it promotes iff the candidate beats the incumbent (amico-catalog Version rule), writing a new {platform}-{kind}-v{N+1} entry (metadata.toml + copied pulse.jld2) with warm_start lineage back to the incumbent.

Exit codes follow the verb convention: agree ≠ trueblocked (64); verified but no beat → no-op (0); promoted → 0; usage/missing-artifact → 64.

Design

  • Pure core in repertoire.ts (loaders never throw — a corrupt/missing catalog degrades to empty, like src/catalog.ts's template/exemplar loaders); the verb body (arg parsing + writes) in catalog_verb.ts. verbs.ts wires catalog.run to it and marks it non-stub (a stub? flag so --help drops the [stub → …] tag for catalog only); vault/device/note stay B1 stubs. One impl backs both the CLI (amico.ts) and the mcp-serve facade (unchanged).
  • $AMICO_CATALOG_DIR overrides the pulses dir (tests point it at a temp catalog).

Flag-name note (S31 guard) — reviewer decision point

test/s31.test.ts bans the physics-knob double-dash flags (gate/pulse/system) anywhere in src/. So the gate discriminator is --kind (issue #111's acceptance surface; maps onto the repertoire's gate field), and the pulse-artifact path is --artifact rather than the issue's literal --pulse — a pulse-file path is not a physics knob (same category as --spec/--from-run), so it takes a non-colliding name. If you'd rather keep the literal --pulse, the alternative is an explicit, reviewed S31 carve-out amendment (the precedent mcp_serve.ts cites for spec C).

Tests

  • test/repertoire.test.ts-style pure-logic tests + query/ingest through the dist/amico.js bundle (test/catalog_verb.test.ts, 19 tests), mirroring amico.test.ts / subcommands.test.ts.
  • amico.test.ts's stub loop drops catalog (now real) and asserts it routes to query/ingest; vault/device/note still asserted as stubs.
  • amico-run: 141 passed (18 files). Extension fast suite: 435 passed, 3 skipped. Typecheck clean. No Julia-gated slow tests run (none apply to this slice).

Integration follow-up (out of scope here, per the slice)

This slice lands the CLI verb + tests only; it does not rewire the extension/interview. The remaining plugin→CLI migration: today the opencode interview has noamicode_catalog plugin tool (warm-start lookup is currently done ad hoc / not wired to the repertoire), and promotion lives in the extension's manual "Save pulse to catalog" quick-pick (run_controls.catalogPulsesDir). Issue #111's second acceptance box — "opencode interview does warm-start lookups via the CLI verb (bash)" — means wiring the interview's warm-start step to shell out to amico catalog query (and, optionally, routing promotion through amico catalog ingest so the verification.agree gate is enforced in one place). That belongs in the extension scores//plugin wiring, not amico-run, and should be its own slice/PR so this one stays reviewable.

Note: fork CI may be RED (pre-existing private-fork vendored-binary token issue), unrelated to this change.

🤖 Generated with Claude Code

Replace the B1 `catalog` stub with a working spine bookkeeping verb backed by
the pulse repertoire (~/.amico/vaults/armonissima/catalog/pulses/<id>/metadata.toml,
the amico-catalog skill's Phase-0 schema). Two subcommands, both deterministic
filesystem work callable via bash by either runtime, the harness, or cron/CI:
amico catalog query --platform <p> --kind <g>
→ the incumbent pulse metadata for (platform, gate) + the ranked candidate
list (fidelity desc; ties broken by shorter duration). This is the
warm-start lookup the interview does before authoring a solve.
amico catalog ingest --platform <p> --kind <g> [--from-run <dir>]
[--artifact <file.jld2>] [--fidelity <f>] [--agree …] …
→ the PROMOTION path, GATED on verification.agree (matching the existing
semantics — a run is promotable only when the independent re-rollout
agreed: verification.toml `agree = true`; --from-run reads it, or pass
--agree explicitly). When gated open it promotes iff the candidate beats
the incumbent (amico-catalog Version rule), writing a new
{platform}-{kind}-v{N+1} entry (metadata.toml + copied pulse.jld2) with
`warm_start` lineage back to the incumbent. agree≠true → blocked (64);
no beat → no-op (0); promoted → 0.
Design notes:
- Pure core in repertoire.ts (loaders never throw; a corrupt/missing catalog
degrades to empty, like src/catalog.ts's template/exemplar loaders); the verb
body (arg parsing + writes) in catalog_verb.ts. verbs.ts wires catalog.run to
it and marks it non-stub; vault/device/note stay B1 stubs. One impl backs both
the CLI (amico.ts) and the mcp-serve facade (unchanged).
- $AMICO_CATALOG_DIR overrides the pulses dir (tests point it at a temp catalog).
- FLAG NAMES honor the S31 guard (test/s31.test.ts bans the physics-knob
double-dash flags gate/pulse/system in src/): the gate discriminator is `--kind`
(issue #111's surface, maps to the `gate` field) and the pulse-artifact PATH is
`--artifact` (a file path, not a physics knob — same category as spec/from-run).
Tests: repertoire pure logic + query/ingest through the dist/amico.js bundle
(mirrors amico.test.ts / subcommands.test.ts); amico.test.ts's stub loop drops
catalog (now real) and asserts it routes to query/ingest. amico-run 141 green,
extension fast suite 435 green. Stacks on #118 (B1).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jack-champagne

Copy link
Copy Markdown
Member

Closing — this is already delivered. The work is on main; the PR was only ever paperwork left open by the stacked-branch flow.

b2-catalog-verb tip 0fd846d is a direct ancestor of main (d03d3c8), and git diff main...b2-catalog-verb is empty — nothing here is missing from main.

This PR targeted b1-amico-cli-router, which is itself already fully in main, so the diff shown on GitHub was never against a live base.

Branch preserved.

Sign up for freeto 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.

2 participants

@aarontrowbridge@jack-champagne
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

amico catalog (#111): B2 — real repertoire query + verified ingest verb - #119

Closed
aarontrowbridge wants to merge 1 commit into
b1-amico-cli-routerfrom
b2-catalog-verb
Closed

amico catalog (#111): B2 — real repertoire query + verified ingest verb#119
aarontrowbridge wants to merge 1 commit into
b1-amico-cli-routerfrom
b2-catalog-verb

Conversation

@aarontrowbridge

Copy link
Copy Markdown
Member

Closes#111. Stacks on #118 (B1 — the amico verb router); base branch is b1-amico-cli-router, not main. Review/merge #118 first.

What this does

Replaces B1's catalogstub with a working spine bookkeeping verb backed by the pulse repertoire~/.amico/vaults/armonissima/catalog/pulses/<id>/metadata.toml (the amico-catalog skill's Phase-0 schema). Both subcommands are deterministic filesystem work, callable via bash by either runtime, the harness, or cron/CI:

  • amico catalog query --platform <p> --kind <g> → the incumbent pulse metadata for (platform, gate) plus the ranked candidate list (fidelity desc; ties broken by shorter duration). This is the warm-start lookup the interview does before authoring a solve.
  • amico catalog ingest --platform <p> --kind <g> [--from-run <dir>] [--artifact <file.jld2>] [--fidelity <f>] [--agree true|false] … → the promotion path, gated on verification.agree (matching the existing semantics — a run is promotable only when the independent re-rollout agreed: verification.tomlagree = true). --from-run <dir> reads verification.toml (agree) + result.toml (fidelity) + defaults the artifact to <dir>/pulse.jld2; or pass --agree/--fidelity/--artifact explicitly. When gated open it promotes iff the candidate beats the incumbent (amico-catalog Version rule), writing a new {platform}-{kind}-v{N+1} entry (metadata.toml + copied pulse.jld2) with warm_start lineage back to the incumbent.

Exit codes follow the verb convention: agree ≠ trueblocked (64); verified but no beat → no-op (0); promoted → 0; usage/missing-artifact → 64.

Design

  • Pure core in repertoire.ts (loaders never throw — a corrupt/missing catalog degrades to empty, like src/catalog.ts's template/exemplar loaders); the verb body (arg parsing + writes) in catalog_verb.ts. verbs.ts wires catalog.run to it and marks it non-stub (a stub? flag so --help drops the [stub → …] tag for catalog only); vault/device/note stay B1 stubs. One impl backs both the CLI (amico.ts) and the mcp-serve facade (unchanged).
  • $AMICO_CATALOG_DIR overrides the pulses dir (tests point it at a temp catalog).

Flag-name note (S31 guard) — reviewer decision point

test/s31.test.ts bans the physics-knob double-dash flags (gate/pulse/system) anywhere in src/. So the gate discriminator is --kind (issue #111's acceptance surface; maps onto the repertoire's gate field), and the pulse-artifact path is --artifact rather than the issue's literal --pulse — a pulse-file path is not a physics knob (same category as --spec/--from-run), so it takes a non-colliding name. If you'd rather keep the literal --pulse, the alternative is an explicit, reviewed S31 carve-out amendment (the precedent mcp_serve.ts cites for spec C).

Tests

  • test/repertoire.test.ts-style pure-logic tests + query/ingest through the dist/amico.js bundle (test/catalog_verb.test.ts, 19 tests), mirroring amico.test.ts / subcommands.test.ts.
  • amico.test.ts's stub loop drops catalog (now real) and asserts it routes to query/ingest; vault/device/note still asserted as stubs.
  • amico-run: 141 passed (18 files). Extension fast suite: 435 passed, 3 skipped. Typecheck clean. No Julia-gated slow tests run (none apply to this slice).

Integration follow-up (out of scope here, per the slice)

This slice lands the CLI verb + tests only; it does not rewire the extension/interview. The remaining plugin→CLI migration: today the opencode interview has noamicode_catalog plugin tool (warm-start lookup is currently done ad hoc / not wired to the repertoire), and promotion lives in the extension's manual "Save pulse to catalog" quick-pick (run_controls.catalogPulsesDir). Issue #111's second acceptance box — "opencode interview does warm-start lookups via the CLI verb (bash)" — means wiring the interview's warm-start step to shell out to amico catalog query (and, optionally, routing promotion through amico catalog ingest so the verification.agree gate is enforced in one place). That belongs in the extension scores//plugin wiring, not amico-run, and should be its own slice/PR so this one stays reviewable.

Note: fork CI may be RED (pre-existing private-fork vendored-binary token issue), unrelated to this change.

🤖 Generated with Claude Code

Replace the B1 `catalog` stub with a working spine bookkeeping verb backed by
the pulse repertoire (~/.amico/vaults/armonissima/catalog/pulses/<id>/metadata.toml,
the amico-catalog skill's Phase-0 schema). Two subcommands, both deterministic
filesystem work callable via bash by either runtime, the harness, or cron/CI:
amico catalog query --platform <p> --kind <g>
→ the incumbent pulse metadata for (platform, gate) + the ranked candidate
list (fidelity desc; ties broken by shorter duration). This is the
warm-start lookup the interview does before authoring a solve.
amico catalog ingest --platform <p> --kind <g> [--from-run <dir>]
[--artifact <file.jld2>] [--fidelity <f>] [--agree …] …
→ the PROMOTION path, GATED on verification.agree (matching the existing
semantics — a run is promotable only when the independent re-rollout
agreed: verification.toml `agree = true`; --from-run reads it, or pass
--agree explicitly). When gated open it promotes iff the candidate beats
the incumbent (amico-catalog Version rule), writing a new
{platform}-{kind}-v{N+1} entry (metadata.toml + copied pulse.jld2) with
`warm_start` lineage back to the incumbent. agree≠true → blocked (64);
no beat → no-op (0); promoted → 0.
Design notes:
- Pure core in repertoire.ts (loaders never throw; a corrupt/missing catalog
degrades to empty, like src/catalog.ts's template/exemplar loaders); the verb
body (arg parsing + writes) in catalog_verb.ts. verbs.ts wires catalog.run to
it and marks it non-stub; vault/device/note stay B1 stubs. One impl backs both
the CLI (amico.ts) and the mcp-serve facade (unchanged).
- $AMICO_CATALOG_DIR overrides the pulses dir (tests point it at a temp catalog).
- FLAG NAMES honor the S31 guard (test/s31.test.ts bans the physics-knob
double-dash flags gate/pulse/system in src/): the gate discriminator is `--kind`
(issue #111's surface, maps to the `gate` field) and the pulse-artifact PATH is
`--artifact` (a file path, not a physics knob — same category as spec/from-run).
Tests: repertoire pure logic + query/ingest through the dist/amico.js bundle
(mirrors amico.test.ts / subcommands.test.ts); amico.test.ts's stub loop drops
catalog (now real) and asserts it routes to query/ingest. amico-run 141 green,
extension fast suite 435 green. Stacks on #118 (B1).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jack-champagne

Copy link
Copy Markdown
Member

Closing — this is already delivered. The work is on main; the PR was only ever paperwork left open by the stacked-branch flow.

b2-catalog-verb tip 0fd846d is a direct ancestor of main (d03d3c8), and git diff main...b2-catalog-verb is empty — nothing here is missing from main.

This PR targeted b1-amico-cli-router, which is itself already fully in main, so the diff shown on GitHub was never against a live base.

Branch preserved.

Sign up for freeto 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.

2 participants

@aarontrowbridge@jack-champagne