Skip to content

Feat/astra model - #91

Closed
thisguymartin wants to merge 19 commits into
ericlitman:mainfrom
thisguymartin:feat/astra-model
Closed

thisguymartin wants to merge 19 commits into
ericlitman:mainfrom
thisguymartin:feat/astra-model

Conversation

@thisguymartin

Copy link
Copy Markdown

Closes #

What changed

Verification

  • Bun tests, strict typecheck, static invariants, and plugin validation pass.
  • The exact candidate is installed in every affected harness.
  • The changed behavior passes from each real user surface.
  • The installed version, action, and observed result appear below.

Live evidence:

A pull request without live evidence remains a draft. Do not merge, tag, release, or roll it out.

Fork of ericlitman/open-pstack at v1.4.1 (de67e6b). UPSTREAM-FLEX.md adds
the second sync layer (cursor -> open-pstack -> flex) with the merge
rehearsal procedure and the expected conflict surface for upstream 1.5.0.
NOTICE.md records the provenance chain, LICENSE adds the fork copyright
line without removing existing holders, and the README gains a fork
section stating what flex adds and that a stock install behaves exactly
like upstream.
New gateway lanes run the stock claude binary against each lab's
Anthropic-compatible endpoint, reusing the exact claude argv and the
existing spawn path. flex-providers.ts owns the per-provider env maps:
endpoint (overridable), ANTHROPIC_AUTH_TOKEN from DEEPSEEK_API_KEY or
MINIMAX_API_KEY, model pins, nonessential-traffic and attribution-header
hygiene, and an isolated CLAUDE_CONFIG_DIR under ~/.pstack-flex.
childEnvironment deletes inherited ANTHROPIC_* values before injection so
a parent session's credentials or endpoint never bleed into a gateway
child.

- Preflight is claude --version: auth-status semantics under token auth
  are undocumented, credentials are checked in-process, and the one-shot
  invocation is the real auth test.
- Gateway receipts force costUsd to null (the CLI prices total_cost_usd
  at Anthropic rates, fiction for third-party traffic); token usage stays.
- Served models match case-insensitively (MiniMax-M3 vs minimax-m3) and
  otherwise fall back to modelEvidence pinned-argv like Codex.
- provider==parent stays rejected; gateway providers are distinct, so
  they run under both parents through the external runner.
A gateway lane refuses to start, in-process and before any subprocess,
when its API key variable is missing or its isolated config dir carries
a claude.ai OAuth credentials file (or one that cannot be parsed). The
refusal is an unauthenticated receipt (exit 77) whose evidence names the
path and never the contents. This guarantees a claude.ai login can never
be pointed at a third-party endpoint through the runner. Endpoint
authentication errors from the one-shot invocation classify as
unauthenticated through the existing stderr matching. Tests cover the
key-missing, OAuth-refusal, garbage-file, env-injection, happy-path,
case-shifted-model, pinned-argv, and endpoint-401 paths, plus the
zero-subscription scenario with mocked binaries; nothing performs
network I/O.
PROVIDERS now spreads GATEWAY_PROVIDERS, and the preflight, invocation,
parse, and preflight-pass paths branch on isGatewayProvider instead of
naming deepseek and minimax in each switch. Adding an Anthropic-compatible
gateway is one GATEWAY_PROVIDERS entry plus one GATEWAY_SPECS row; the
Record type makes a missing spec a compile error.
provider-dispatch.md gains an additive Flex model matrix section (the
stock matrix and its parser contract stay byte-identical), deepseek/
minimax columns in the route table (external runner under both parents),
the gateway preflight and receipt semantics, and the panel diversity
rule: arena runners and interrogate reviewers span at least two distinct
providers unless the operator explicitly confirms otherwise. codex-tools
notes that flex descriptors are never spawn_agent lanes.
Mirrors upstream PR ericlitman#73 (issue ericlitman#72): role assignments are chosen first,
only assigned families get effort questions and probes, and there is no
requirement to assign every matrix family. A failed model demands
explicit repair or role reassignment before saving; the fail-closed
write rules and the first-run sheet bytes are unchanged. The probe table
gains DeepSeek and MiniMax rows (key present, config dir free of OAuth
credentials, one-turn probe doubling as the base-URL confirmation), and
render-time validation enforces non-empty roles, at least two architect
runners, and the two-provider panel diversity rule. model-matrix.test.ts
is updated in the same commit because it pins the setup prose, and gains
a flex-matrix section check cross-validated against the runner's
gateway specs.
LANES.md covers lane kinds, the gateway environment reference, dated
prices including DeepSeek's off-peak window, the zero-subscription
walkthrough (parent session env-pointed at DeepSeek, MiniMax through the
runner), safety rules (unsupported-not-prohibited, never a claude.ai
login on a gateway path, per-project privacy opt-in, no silent
substitution), the optional OpenRouter and future Ollama lanes, and the
live post-merge validation checklist. CHANGES.md records the flex delta.
docs/USAGE.md walks the whole plugin: what pstack-flex is and how it
relates to thisguyskills, a mermaid map of task -> poteto-mode ->
playbooks -> lane fan-out -> receipts, fork install commands, key
handling for gateway lanes, the assignment-first /setup-pstack flow
with three worked configurations (full frontier, hybrid saver,
zero-subscription duo), copy-paste prompts for poteto-mode,
interrogate, arena, swarm, and architect with panel diagrams, a
sequence diagram of gateway lane execution including the OAuth guard,
a receipt field cheat-sheet, a cost playbook, and a troubleshooting
table keyed to receipt statuses.

docs/LANES.md gains a "Storing keys" section: macOS Keychain
load-on-demand recipe, pass/secret-tool and 1Password CLI
alternatives, the direnv plaintext caveat, the honest threat model,
and provider spend caps as the real blast-radius control.
The fork section now points newcomers at docs/USAGE.md, and the
install commands move from ericlitman/open-pstack to this repository.
The marketplace and plugin names are unchanged (pstack@open-pstack),
so only the marketplace-add commands change.
Lists the four touch points (GATEWAY_PROVIDERS, GATEWAY_SPECS, the flex
matrix row, the setup probe row) and which check fails when each is missing.
feat(runner): DeepSeek and MiniMax gateway lanes
feat(setup): flex dispatch matrix, assignment-first setup, and lane docs
Add DeepSeek Pro and MiniMax preview model choices
Add Astra, GPT-6 Sol, and Luna as optional model families for setup-pstack. Keep upstream defaults intact and validate their provider routes and effort flags.
@mergify

mergify Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

This pull request does not currently match the merge queue conditions, so it cannot be queued from here. The box comes back if it matches again.

@greptile-apps

greptile-apps Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 2/5

[Medium risk] Adds optional gateway providers and new model families to the runner.

The PR is not ready to merge because gateway children receive unrelated API keys and configured panels can discard successful gateway results.

Findings

  1. P1 Security Gateway children inherit other keys ▶
  2. P1 Panels reject successful gateway lanes ▶
  3. P2 Security Plaintext endpoint overrides expose tokens ▶

Summary

The PR adds DeepSeek and MiniMax gateway lanes, optional GPT-6 Codex families, assignment-first setup, and accompanying documentation and runner tests.

  • Gateway environment isolation needs to exclude credentials for other providers.
  • Gateway receipt acceptance needs to be consistent across the runner and panel skills.
  • Endpoint overrides need a transport-safety check.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart LR
  P[Parent environment and role sheet] --> R[External runner]
  R --> G[Gateway guard and environment]
  G --> C[claude child]
  C --> E[DeepSeek or MiniMax endpoint]
  C --> Q[Receipt]
  Q --> A[Arena and interrogate]
Loading

Reviews (1) · Last reviewed commit: "feat(pstack): support GPT-6 role familie..."

Comment on lines +149 to +154
if (isGatewayProvider(provider)) {
for (const key of Object.keys(result)) {
if (key.startsWith("ANTHROPIC_")) delete result[key];
}
for (const key of GATEWAY_INHERITED_CONFLICTS) delete result[key];
Object.assign(result, gatewayEnvironment(provider, model, source));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 security Gateway children inherit other keys

When both gateway keys are loaded, a DeepSeek lane inherits MINIMAX_API_KEY, and a MiniMax lane inherits DEEPSEEK_API_KEY. The environment cleanup removes ANTHROPIC_* values but not the other provider’s key. Commands run by the child can access that unrelated credential, even in read-only mode, which permits Bash. Remove unrelated gateway keys before spawning each child.

How this was verified: The runner copies the parent environment, leaves the sibling provider’s key in it, and passes that environment to the gateway child.

1. Exit status `0`.
2. Receipt status `complete`.
3. Either `modelVerified: true` with `modelEvidence: "provider-report"`, or a Codex receipt with `reportedModel: null`, `modelVerified: false`, and `modelEvidence: "pinned-argv"`. For Claude's `fable` and `opus` aliases, the concrete provider report must belong to the requested family. Codex 0.149.0 accepts the exact `--model` argument but does not report the served model in its JSONL stream.
3. Either `modelVerified: true` with `modelEvidence: "provider-report"`, or a Codex receipt with `reportedModel: null`, `modelVerified: false`, and `modelEvidence: "pinned-argv"`, or a gateway (`deepseek`/`minimax`) receipt with `modelVerified: false` and `modelEvidence: "pinned-argv"` when the endpoint does not echo the requested slug. For Claude's `fable` and `opus` aliases, the concrete provider report must belong to the requested family. Codex 0.149.0 accepts the exact `--model` argument but does not report the served model in its JSONL stream. Gateway reports match case-insensitively because third-party endpoints are inconsistent about slug casing.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Panels reject successful gateway lanes

If a gateway does not report its model, the runner can return a complete receipt with modelVerified: false and modelEvidence: "pinned-argv". This new success condition conflicts with the panel skills: arena accepts pinned-argv evidence only for Codex, while interrogate requires a model-verified receipt. A successfully completed gateway candidate or reviewer can therefore be discarded from the panel. Update those consumers to accept the new receipt condition.

): NodeJS.ProcessEnv {
const spec = GATEWAY_SPECS[provider];
const injected: NodeJS.ProcessEnv = {
ANTHROPIC_BASE_URL: overridden(source, spec.baseUrlOverrideVar) ?? spec.baseUrlDefault,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 security Plaintext endpoint overrides expose tokens

If an operator sets a non-loopback gateway endpoint override to http://, this code accepts it while giving the same child the provider key as ANTHROPIC_AUTH_TOKEN. That can expose the key in transit. Validate the override’s scheme before spawning, with an explicit local-only exception if needed.

How this was verified: The override receives only a nonblank check, then the runner passes it and the provider token together to the gateway child.

# Conflicts:
#	plugins/pstack/skills/poteto-mode/scripts/runner/model-matrix.test.ts
Add the astra, sol-6, and luna families to the lane guide, usage guide,
reference, README, and fork-ownership list. Existing sheets and first-run
defaults stay on codex:gpt-5.6-sol@max.
@thisguymartin
thisguymartin deleted the feat/astra-model branch September 28, 2026 17:33
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