Skip to content

feat: add allium behavioral specs - #5

Closed
exilis wants to merge 6 commits into
mainfrom
allium/behavioral-specs
Closed

feat: add allium behavioral specs#5
exilis wants to merge 6 commits into
mainfrom
allium/behavioral-specs

Conversation

@exilis

@exilis exilis commented May 27, 2026

Copy link
Copy Markdown

Behavioral Specifications

Machine-distilled from source code using allium-spec-distillation.

credential-resolution

External Entities

Review notes:

  • [minor] CredentialsRequested event used in SelectProfileName's when: clause but never explicitly declared as a trigger or surface; its shape (requested_profile?) is only implied by usage

oauth-flow

Authorization-code OAuth2 flow for CLI user authentication.
Currently restricted to paper trading; live trading requires API keys until PKCE is added.

Review notes:

  • [minor] config.token_exchange_timeout is declared but never referenced in any rule; either wire it to a rule or remove it

http-client

Value Types

Review notes:

  • [minor] RequestError value type is declared but never referenced in any rule ensures or requires clause — appears orphaned
  • [minor] HttpClient.timeout field is declared but no rule models timeout behaviour (e.g. request failing or retrying on timeout)
  • [minor] No rule covers non-rate-limit client error responses (4xx other than 429) — silent gap in the response-handling lifecycle

output-contract

Two-tier output model: API commands emit structured data (JSON or CSV)
to stdout with JSON errors on stderr; operational commands emit plain
text. Covers jq-filter transformation and CSV formatting support.

hand-authored-commands

Scope: Hand-authored CLI command logic for the Alpaca CLI
Includes: bracket-order leg construction with time-in-force defaulting,
watchlist by-name asset removal, self-update discovery and upgrade,
doctor diagnostics, credential profile management
Excludes: generated Cobra command tree (internal/cmd/commands.gen.go),
raw API passthrough (api.go), factory helpers (factory.go),
help-all rendering (help_all.go)

code-generator

Scope: OAS-driven code generation pipeline in cmd/generate/
Includes: command registry (CommandMapping), generation pipeline, coverage validation
Excludes:
- Output files: internal/api/*.gen.go, internal/cmd/commands.gen.go
- Hand-written extension points: bodyHook and configureFunc implementations
- OAS specification source files (api/specs/)

Review notes:

  • [minor] output_path in RunGenerator rule uses literal string "internal/api/descriptions.gen.go" and "internal/cmd/commands.gen.go" — these are implementation-level paths rather than domain terms; consider replacing with symbolic path references or abstract output identifiers
  • [minor] type_output_path() and client_output_path() helper functions are referenced in ensures: clauses but never declared in the spec; their signatures and semantics are implicit

🤖 Generated with allium-spec-distillation

Added: fix for this PR's own Allium Check gate

This PR introduces .github/workflows/allium-check.yml. That workflow's gate was broken, so a commit has been added here to fix it rather than opening a separate PR.

What was wrong. The gate ran allium check and then grepped its output for an N error(s) summary line to decide pass/fail. allium 3.5.0 and 3.5.3 emit JSON and never print that string, so the grep matched nothing, the script hit its own could not parse allium check summary branch, and the job failed unconditionally — independently of spec content. Every Allium Check run across the org has been red since 2026-07-22 for this reason.

Why the exit code alone is not the fix. allium check --help documents exit 1 as "One or more errors or warnings were reported". Specs carry warnings that cannot be removed (externalEntity.missingSourceHint, and use.unresolvedPath for shared-library imports, which allium 3.5.x cannot resolve locally at all). Gating on the exit code would keep this job red for reasons unrelated to correctness — which is exactly what the original code comment was trying to avoid.

What it does now. Parses the diagnostics and fails only on severity == "error". allium emits one JSON document per spec file, concatenated, so the stream is slurped with jq -s rather than read as a single object. The older human-readable summary is still accepted as a fallback, because runner caches are not uniform across repos. If neither format parses, the job fails loudly — a gate that cannot read its own input must never report green.

Verified by running both allium 3.5.0 and 3.5.3 against real specs in this org: 0 errors + warnings → PASS (previously FAIL), specs with real errors → FAIL, unparseable input → FAIL.

  • This branch is 2 commit(s) behind its base. It still merges cleanly (verified with git merge-tree, no merge performed), so the distance alone is not a conflict — it is noted here so a reviewer does not have to work that out.

The spec content of this PR is unchanged by that commit; it touches only the workflow file.

exilis and others added 6 commits May 27, 2026 13:27
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds two GitHub Actions workflows:
- allium-check.yml: validates .allium file syntax via allium-cli 3.0.4.
- allium-drift.yml: thin caller for the reusable drift check in
  alpacahq/alpaca-harness. Auto-detects LLM provider from whichever
  secret is set (ANTHROPIC_API_KEY or CURSOR_API_KEY). Advisory mode
  (required_passing: false) — findings post as PR comments, do not
  block merging.

Prerequisite for drift checks: set one of ANTHROPIC_API_KEY or
CURSOR_API_KEY as a repo secret. Without it, the drift job fails
fast with a clear error.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drift review against main found no spec-relevant changes: the three new
base commits are OAS-regenerated outputs (*.gen.go, goldens) and README
cleanup; the generator, credential-resolution, http-client, oauth and
output-contract behavior the specs model is unchanged. All six specs
pass allium check 3.5.0 with 0 errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Consolidated onto this branch rather than opening a new PR.
Corrects spec-vs-code divergence, fills gaps, adds surfaces/contracts,
and records unresolved intent as open questions. allium check: 0 errors.
The gate grepped for an "N error(s)" summary. allium 3.5.0 and 3.5.3 emit
JSON and never print that string, so the job failed unconditionally,
independent of spec content -- verified directly against both binaries.

The raw exit code cannot replace the grep either: "allium check --help"
documents exit 1 as "one or more errors OR WARNINGS were reported", and
specs carry unavoidable warnings (externalEntity.missingSourceHint,
use.unresolvedPath). Gating on the exit code would keep CI red for
content-free reasons -- exactly what the original comment set out to avoid.

The gate now parses diagnostics and fails only on severity == error.
allium emits one JSON document per spec file, concatenated, so the stream
is slurped with "jq -s". The legacy text summary is retained as a fallback
because runner caches are not uniform across repos. If neither format
parses, the job fails loudly rather than reporting green.

Verified against real output: forex 0 err / 2 warn PASS, banking 0/7 PASS,
cli 0/0 PASS, data-warehouse 4 err FAIL, unparseable input FAIL.
@exilis exilis closed this Aug 9, 2026
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