Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .agents/skills
1 change: 1 addition & 0 deletions .claude/skills
19 changes: 19 additions & 0 deletions .codex/skills/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Skill Registry

Last updated: 2026-03-02

| Skill | File | Triggers | Priority |
|---|---|---|---|
| Language Feature Development | [language-feature-development.md](./language-feature-development.md) | grammar, parser, syntax, AST, opcode, new expression, new requirement | Core |
| Testing and Regressions | [testing-and-regressions.md](./testing-and-regressions.md) | test, regression, fixture, assertion, CLI parity, coverage | Core |
| WASM Playground Workflow | [wasm-playground-workflow.md](./wasm-playground-workflow.md) | playground, wasm-pack, contracts.js, GitHub Pages, browser demo | Core |
| Compiler Debugging | [compiler-debugging.md](./compiler-debugging.md) | parse error, asm mismatch, compile failure, introspection fallback | Core |

## Missing Skills (Recommended)
- [ ] Release and versioning workflow (`release-management.md`)
- [ ] Security review checklist for script-generation changes (`security-review.md`)
- [ ] Performance profiling for parser/compiler hot paths (`performance-profiling.md`)

## Notes
- Canonical location: `.codex/skills/`
- Compatibility symlinks: `.claude/skills`, `.agents/skills`
77 changes: 77 additions & 0 deletions .codex/skills/compiler-debugging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
name: compiler-debugging
description: Activate this skill for parse failures, incorrect opcode output, variant mismatches, or unclear compiler behavior. Use it aggressively when bug reports include `Parse error`, wrong ASM, or failing integration tests.
prerequisites: cargo, familiarity with parser/compiler paths
---

# Compiler Debugging

<purpose>
Diagnose compiler defects quickly by isolating stage failures and tracing data flow from grammar to AST to emitted ASM.
</purpose>

<context>
The compiler path is deterministic:
- Parse source into AST (`src/parser/mod.rs`)
- Convert AST statements/requirements into ABI and ASM (`src/compiler/mod.rs`)
Most production defects are one of:
1. Grammar/parser mismatch
2. AST variant emitted incorrectly
3. Dual-path generation mismatch (`serverVariant` behavior)
</context>

<procedure>
1. Reproduce with smallest contract snippet that still fails.
2. Identify failure stage:
- `Parse error:` prefix -> parser/grammar
- Compilation succeeds but wrong ASM -> compiler emission
- CLI-only failure -> `src/main.rs` I/O/arg handling
3. Add or update a targeted integration test before patching.
4. Trace affected path:
- Grammar rule -> parser `parse_*` function
- AST variant -> `emit_expression_asm` / `generate_requirement_asm`
- Variant behavior -> `generate_function`
5. Implement minimal fix and run:
- `cargo fmt --check`
- `cargo test --test <focused_file>`
- `cargo test`
6. Keep the reproducer test as regression coverage.
</procedure>

<patterns>
<do>
- Classify bug by stage before editing code.
- Use opcode string joins in tests when full vector matching is brittle.
- Validate both cooperative and exit variants when fixing semantic bugs.
</do>
<dont>
- Do not patch compiler first when parser is failing to build AST.
- Do not remove tests to make suite pass.
- Do not ignore warnings that indicate dead paths for newly added variants.
</dont>
</patterns>

<examples>
Example: parse-vs-emit triage
```text
If error starts with "Parse error:", fix grammar/parser.
If test compiles but ASM misses expected opcode, fix compiler emission branch.
If only CLI path fails, inspect file extension/output path logic in src/main.rs.
```
</examples>

<troubleshooting>
| Symptom | Cause | Fix |
|---|---|---|
| `Parse error: ...` for valid-looking syntax | PEG rule order mismatch | Reorder grammar alternatives and parser mapping |
| Exit variant unexpectedly uses introspection ops | Fallback branch bypassed | Inspect `generate_function` introspection conditional |
| Function inputs unexpectedly expanded | Array flattening behavior | Check `DEFAULT_ARRAY_LENGTH` handling in compiler |
</troubleshooting>

<references>
- `src/parser/grammar.pest`: parse surface area
- `src/parser/mod.rs`: parser implementation
- `src/compiler/mod.rs`: variant and opcode emission logic
- `src/main.rs`: CLI argument/file handling
- `tests/*.rs`: behavior contracts and regression signals
</references>
83 changes: 83 additions & 0 deletions .codex/skills/language-feature-development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
name: language-feature-development
description: Activate this skill whenever Arkade language syntax, grammar precedence, AST variants, opcode emission, or ABI semantics change. Use it for any request mentioning new keywords, operators, expressions, require forms, or function generation behavior.
prerequisites: Rust toolchain with cargo; familiarity with parser/compiler/model modules
---

# Language Feature Development

<purpose>
Implement language/compiler features safely by enforcing synchronized edits across grammar, parser, AST models, opcode emission, and integration tests.
</purpose>

<context>
This project is a single Rust crate. Core feature pipeline:
1. Grammar (`src/parser/grammar.pest`)
2. Parser mapping (`src/parser/mod.rs`)
3. AST/ABI models (`src/models/mod.rs`)
4. ASM emission (`src/compiler/mod.rs`)
5. Integration coverage (`tests/*.rs`)

Non-internal functions emit dual variants. Introspection paths have special exit behavior (N-of-N fallback), so feature edits can impact both variants.
</context>

<procedure>
1. Classify the feature:
- Syntax-only (parse and preserve)
- Semantic (changes emitted ASM/requirements)
- ABI-shape (changes `ContractJson`/`FunctionInput`)
2. Update `src/models/mod.rs` first when new AST variants are needed.
3. Update grammar in `src/parser/grammar.pest` with careful PEG ordering.
4. Map new rules in `src/parser/mod.rs` via explicit `parse_*` function paths.
5. Implement emission in `src/compiler/mod.rs`:
- Requirement generation (`require` metadata)
- Expression/statement ASM emission
- Dual-path behavior when relevant
6. Add integration tests in `tests/`:
- Happy path
- Edge condition
- Variant expectations (`serverVariant` true/false)
7. Run validation: `cargo fmt --check && cargo test`.
8. If examples should demonstrate the feature, update `examples/*.ark` and regenerate playground contracts.
</procedure>

<patterns>
<do>
- Keep one-to-one mapping between grammar alternatives and parser branches.
- Add minimal helper functions rather than growing one giant match arm.
- Assert exact opcodes in tests for semantic features.
- Test both parser success and output shape when changing AST.
</do>
<dont>
- Do not add grammar rules without parser handling -> use explicit parse branch instead.
- Do not change `Expression`/`Requirement` enums without compiler emission support.
- Do not rely on README examples as behavior source -> use code/tests.
</dont>
</patterns>

<examples>
Example: Add new transaction property check
```rust
// 1) models: add Expression variant if needed
// 2) grammar: add token to tx_introspection rule
// 3) parser: map rule -> Expression::TxIntrospection { property }
// 4) compiler: map property -> OP_INSPECT* opcode in emit_tx_introspection_asm
// 5) test: assert opcode exists in server variant ASM
```
</examples>

<troubleshooting>
| Symptom | Cause | Fix |
|---|---|---|
| `Parse error: Unexpected rule` | Grammar added but parser match missing | Add parser branch and conversion function |
| Feature parses but ASM unchanged | Compiler emission path not wired | Update `generate_expression_asm`/`emit_expression_asm` or requirement mapping |
| Only one variant behaves correctly | Dual-path logic not handled | Inspect `generate_function` and add variant-specific tests |
</troubleshooting>

<references>
- `src/parser/grammar.pest`: language grammar and operator precedence
- `src/parser/mod.rs`: parse functions and AST construction
- `src/models/mod.rs`: AST/ABI type definitions
- `src/compiler/mod.rs`: requirement + ASM generation
- `tests/new_opcodes_test.rs`: feature-style regression examples
</references>
73 changes: 73 additions & 0 deletions .codex/skills/testing-and-regressions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
name: testing-and-regressions
description: Activate this skill for any test authoring or debugging request, including new contract fixtures, opcode assertions, CLI parity checks, or regression coverage for parser/compiler behavior.
prerequisites: cargo test, rustfmt
---

# Testing and Regressions

<purpose>
Create durable regression tests for compiler behavior, with clear expectations for ABI fields, dual variants, and emitted ASM.
</purpose>

<context>
Testing is integration-heavy under `tests/*.rs`. Typical pattern:
- Build in-memory Arkade contract string
- Call `arkade_compiler::compile`
- Assert contract metadata + function variants + opcode sequence
Some tests also execute CLI binary via `env!("CARGO_BIN_EXE_arkadec")`.
</context>

<procedure>
1. Pick test style:
- Compiler behavior -> integration test using `compile(...)`
- CLI parity -> integration test invoking binary and comparing JSON
2. Write minimal contract fixture inline in test.
3. Assert key behavior:
- Function count and names
- `server_variant` true/false behavior
- Opcode sequence or required opcodes
4. For CLI JSON comparisons, normalize timestamp fields by removing `updatedAt`.
5. Run targeted tests: `cargo test --test <file>`.
6. Run global suite: `cargo test`.
7. Keep tests deterministic (no wall-clock assertions).
</procedure>

<patterns>
<do>
- Use `.find(|f| f.name == "..." && f.server_variant)` for precise variant selection.
- Assert opcodes with constants from `arkade_compiler::opcodes` when available.
- Cover at least one negative/edge branch for new parser features.
</do>
<dont>
- Do not compare full JSON strings containing dynamic `updatedAt` without normalization.
- Do not assert every opcode if behavior can be validated with stable critical subsequences.
- Do not place new behavior without corresponding regression tests.
</dont>
</patterns>

<examples>
Example: CLI parity check skeleton
```rust
let status = std::process::Command::new(env!("CARGO_BIN_EXE_arkadec"))
.arg(input_path)
.arg("-o")
.arg(output_path)
.status()?;
assert!(status.success());
```
</examples>

<troubleshooting>
| Symptom | Cause | Fix |
|---|---|---|
| Test passes locally, fails in CI on formatting | `cargo fmt` not run | Run `cargo fmt` before commit |
| JSON mismatch only on timestamp field | Dynamic `updatedAt` | Remove `updatedAt` from both JSON objects before compare |
| CLI test cannot find binary | Wrong test context or env macro misuse | Use `env!("CARGO_BIN_EXE_arkadec")` in integration tests |
</troubleshooting>

<references>
- `tests/htlc_test.rs`: compile assertions + CLI parity comparison
- `tests/new_opcodes_test.rs`: opcode-focused feature regression style
- `tests/group_properties_test.rs`: broader semantic assertion patterns
</references>
65 changes: 65 additions & 0 deletions .codex/skills/wasm-playground-workflow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
name: wasm-playground-workflow
description: Activate this skill whenever work touches WASM bindings, playground UI behavior, example contract generation, or GitHub Pages deployment for the browser playground.
prerequisites: cargo, wasm-pack, node, python3
---

# WASM Playground Workflow

<purpose>
Safely modify and validate the browser playground pipeline that wraps the Rust compiler as WebAssembly and serves static demo assets.
</purpose>

<context>
Playground stack is static HTML/CSS/JS in `playground/` plus Rust WASM exports in `src/wasm.rs`.
Build flow:
1. `playground/generate_contracts.sh` creates `playground/contracts.js` from `examples/*.ark`.
2. `wasm-pack build --features wasm` outputs package to `playground/pkg`.
3. Deploy workflow publishes `playground/` to GitHub Pages.
</context>

<procedure>
1. If compiler surface changed for web usage, update `src/wasm.rs` first.
2. If example list/content changed, run `./playground/generate_contracts.sh`.
3. Run full build: `./playground/build.sh`.
4. Serve locally: `./playground/serve.sh 8080` and verify browser compile flow.
5. If deploy behavior changed, verify `.github/workflows/deploy-playground.yml` assumptions.
6. Re-run `cargo test` if compiler logic changed.
</procedure>

<patterns>
<do>
- Keep WASM exports string-based for browser ergonomics (`compile` returns JSON string).
- Treat `playground/contracts.js` as generated output.
- Keep playground self-contained (no package manager assumptions).
</do>
<dont>
- Do not hand-edit `playground/pkg/*` artifacts -> regenerate via wasm-pack.
- Do not require npm/yarn setup; current scripts rely only on Node runtime.
- Do not change deploy workflow without explicit approval.
</dont>
</patterns>

<examples>
Example: full local verification
```bash
./playground/generate_contracts.sh
./playground/build.sh
./playground/serve.sh 8080
```
</examples>

<troubleshooting>
| Symptom | Cause | Fix |
|---|---|---|
| `wasm-pack: command not found` | Missing tool | `cargo install wasm-pack` |
| Playground loads but compile fails | WASM package missing or stale | Re-run `./playground/build.sh` |
| New example not in dropdown | `contracts.js` not regenerated | Run `./playground/generate_contracts.sh` |
</troubleshooting>

<references>
- `src/wasm.rs`: wasm-bindgen exports
- `playground/build.sh`: build orchestration
- `playground/generate_contracts.sh`: generated contracts module
- `.github/workflows/deploy-playground.yml`: pages deploy pipeline
</references>
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ Cargo.lock
.env
.env.local

.claude
# Canonical skills are stored in `.codex/skills`.
# Track compatibility symlinks separately (`.claude/skills`, `.agents/skills`).
Loading