Skip to content

feat: add runtime configuration for one-shot token protection via AWF_ONE_SHOT_TOKENS#607

Merged
lpcox merged 11 commits intolpcox/one-shot-token-ld-preloadfrom
copilot/sub-pr-604
Feb 10, 2026
Merged

feat: add runtime configuration for one-shot token protection via AWF_ONE_SHOT_TOKENS#607
lpcox merged 11 commits intolpcox/one-shot-token-ld-preloadfrom
copilot/sub-pr-604

Conversation

Copy link
Contributor

Copilot AI commented Feb 10, 2026

The one-shot token library hardcoded protected token names, requiring recompilation to add custom tokens. This PR adds runtime configuration via the AWF_ONE_SHOT_TOKENS environment variable.

Changes

Runtime Configuration

  • Read AWF_ONE_SHOT_TOKENS at library initialization for custom token list
  • Parse comma-separated values with comprehensive whitespace trimming (isspace())
  • Use strtok_r() instead of strtok() to avoid interfering with application code's tokenizer state
  • Support up to 100 tokens via static allocation
  • Falls back to built-in defaults when unset (GitHub, OpenAI, Anthropic, Codex tokens)
  • Falls back to defaults if AWF_ONE_SHOT_TOKENS parses to zero tokens (e.g., whitespace-only or comma-only strings) to prevent accidental loss of protection

Thread Safety

  • Hold mutex during initialization and token lookup to prevent races
  • Ensure get_token_index() sees consistent token list state
  • strtok_r() usage ensures no interference with application's strtok() calls

Error Handling

  • Clean up allocated tokens before abort on allocation failure
  • Guard against buffer underflow when trimming empty strings
  • Emit warning messages when falling back to defaults due to misconfiguration

Usage

# Protect custom tokens
export AWF_ONE_SHOT_TOKENS="MY_API_KEY,DATABASE_PASSWORD,SECRET_TOKEN"
sudo -E awf --allow-domains example.com -- your-command

When AWF_ONE_SHOT_TOKENS is set with valid tokens, only those tokens are protected (defaults not included). If the variable parses to zero tokens (e.g., ",,," or " "), the library falls back to defaults with warning messages:

[one-shot-token] WARNING: AWF_ONE_SHOT_TOKENS was set but parsed to zero tokens
[one-shot-token] WARNING: Falling back to default token list to maintain protection

Documentation

Updated containers/agent/one-shot-token/README.md with configuration details, fallback behavior, thread-safety notes, and examples for both default and custom token lists.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

…HOT_TOKENS

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
@Mossaka Mossaka marked this pull request as ready for review February 10, 2026 06:21
Copilot AI review requested due to automatic review settings February 10, 2026 06:21
@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

Chroot tests passed! Smoke Chroot - All security and functionality tests succeeded.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

🎬 THE ENDSmoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

Copilot AI and others added 2 commits February 10, 2026 06:23
- Make initialization thread-safe using existing mutex
- Add cleanup of allocated tokens on memory allocation failure
- Use isspace() for comprehensive whitespace trimming (handles newlines, tabs, etc.)

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
- Fix potential buffer underflow when trimming empty strings
- Fix race condition by keeping mutex held during get_token_index() call
- Ensure thread-safe access to token list during lookup

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds runtime configurability to the one-shot token LD_PRELOAD interposer so the set of protected environment variables can be provided via AWF_ONE_SHOT_TOKENS, with updated documentation for defaults and custom configuration.

Changes:

  • Introduces AWF_ONE_SHOT_TOKENS parsing to build a runtime-sensitive token list (falling back to built-in defaults).
  • Updates token tracking to support a configurable list (up to 100 tokens).
  • Updates README with configuration, examples, and expected output for default/custom token scenarios.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
containers/agent/one-shot-token/one-shot-token.c Adds runtime token list initialization from AWF_ONE_SHOT_TOKENS and updates lookup/tracking to use the configured list.
containers/agent/one-shot-token/README.md Documents the new configuration mechanism, defaults, and testing/integration examples.
Comments suppressed due to low confidence (3)

containers/agent/one-shot-token/one-shot-token.c:166

  • The initialization guard in getenv() (static int initializing) isn’t synchronized, so multiple threads can still enter initialization concurrently and/or observe inconsistent state. If you switch to pthread_once (or lock around init), this ad-hoc guard can be removed or made thread-safe.

This issue also appears on line 78 of the same file.


/**
 * Intercepted getenv function
 *
 * For sensitive tokens:
 * - First call: returns the real value, then unsets the variable
 * - Subsequent calls: returns NULL

containers/agent/one-shot-token/one-shot-token.c:102

  • The whitespace-trimming logic can invoke undefined behavior for empty tokens (e.g., consecutive commas in AWF_ONE_SHOT_TOKENS). When strlen(token) is 0, token + strlen(token) - 1 produces an invalid pointer. Handle the zero-length case before computing the end pointer (and skip empty entries safely).
        }

        char *token = strtok(config_copy, ",");
        while (token != NULL && num_tokens < MAX_TOKENS) {
            /* Trim leading whitespace */
            while (*token && isspace((unsigned char)*token)) token++;
            
            /* Trim trailing whitespace */
            char *end = token + strlen(token) - 1;

containers/agent/one-shot-token/one-shot-token.c:85

  • Token list initialization is not thread-safe: tokens_initialized, num_tokens, and sensitive_tokens[] are mutated without synchronization, so concurrent early getenv() calls can race and corrupt the token list / counts. Consider protecting init with pthread_once or the existing token_mutex (double-checked) so initialization happens exactly once.
 * Note: This function must be called with token_mutex held.
 */
static void init_token_list(void) {
    if (tokens_initialized) {
        return;
    }

    /* Get the configuration from environment */

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 86 to 119
const char *config = real_getenv("AWF_ONE_SHOT_TOKENS");

if (config != NULL && config[0] != '\0') {
/* Parse comma-separated token list */
char *config_copy = strdup(config);
if (config_copy == NULL) {
fprintf(stderr, "[one-shot-token] ERROR: Failed to allocate memory for token list\n");
abort();
}

char *token = strtok(config_copy, ",");
while (token != NULL && num_tokens < MAX_TOKENS) {
/* Trim leading whitespace */
while (*token && isspace((unsigned char)*token)) token++;

/* Trim trailing whitespace (only if string is non-empty) */
if (strlen(token) > 0) {
char *end = token + strlen(token) - 1;
while (end > token && isspace((unsigned char)*end)) {
*end = '\0';
end--;
}
}

if (*token != '\0') {
sensitive_tokens[num_tokens] = strdup(token);
if (sensitive_tokens[num_tokens] == NULL) {
fprintf(stderr, "[one-shot-token] ERROR: Failed to allocate memory for token name\n");
/* Clean up previously allocated tokens */
for (int i = 0; i < num_tokens; i++) {
free(sensitive_tokens[i]);
}
free(config_copy);
abort();
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

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

If AWF_ONE_SHOT_TOKENS is set but parses to zero non-empty names (e.g., whitespace-only or ",,"), the library ends up protecting no tokens while still reporting successful initialization. Consider treating an empty parsed list as invalid (fallback to defaults or emit an error) to avoid silently disabling protection due to misconfiguration.

This issue also appears on line 94 of the same file.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in commit 2245791. The library now falls back to the default token list if AWF_ONE_SHOT_TOKENS parses to zero tokens, with warning messages:

[one-shot-token] WARNING: AWF_ONE_SHOT_TOKENS was set but parsed to zero tokens
[one-shot-token] WARNING: Falling back to default token list to maintain protection

This prevents accidentally disabling all protection due to misconfiguration like ",,," or " ".

Comment on lines +94 to +95
}

Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

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

Using strtok() inside an LD_PRELOAD interposer is risky because strtok maintains internal state and can interfere with application code that is also using strtok (if getenv() is called between the app’s strtok() calls). Prefer strtok_r() (or manual parsing) to avoid clobbering global/tokenizer state.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in commit 2245791. Replaced strtok() with strtok_r() which uses a separate state pointer (saveptr) instead of global state. This prevents interference with application code that uses strtok().

Verified with test case that shows application's strtok() calls work correctly even when interleaved with getenv() calls that trigger the library's tokenization.

@github-actions
Copy link
Contributor

C++ Build Test Results

Project CMake Build Status
fmt PASS
json PASS

Overall: PASS

All C++ projects built successfully.

AI generated by Build Test C++

@github-actions
Copy link
Contributor

Build Test: Node.js - Results

Project Install Tests Status
clsx PASS PASS
execa PASS PASS
p-limit PASS PASS

Overall: PASS

All Node.js projects successfully installed dependencies and passed tests.

AI generated by Build Test Node.js

@github-actions
Copy link
Contributor

Rust Build Test Results

Project Build Tests Status
fd 1/1 PASS
zoxide 1/1 PASS

Overall: PASS

All Rust projects built successfully and all tests passed.

AI generated by Build Test Rust

@github-actions
Copy link
Contributor

Smoke Test: Claude - PASS

✅ GitHub MCP: Retrieved last 2 merged PRs

✅ Playwright: Navigated to github.com, title verified
✅ File Write: Created /tmp/gh-aw/agent/smoke-test-claude-21854107060.txt
✅ Bash: Verified file contents

Status: PASS

AI generated by Smoke Claude

@github-actions
Copy link
Contributor

Bun Build Test Results

Project Install Tests Status
elysia 1/1 PASS
hono 1/1 PASS

Overall: PASS

All Bun projects installed and tested successfully.

AI generated by Build Test Bun

@github-actions
Copy link
Contributor

Build Test: Deno - Results

Project Tests Status
oak 1/1 ✅ PASS
std 1/1 ✅ PASS

Overall: ✅ PASS

All Deno tests completed successfully.

AI generated by Build Test Deno

@github-actions
Copy link
Contributor

❌ Java Build Test Failed

Status: CONFIGURATION ERROR

Issue

Java/Maven builds cannot access Maven Central repository through AWF firewall. The firewall does not automatically configure Java proxy settings.

Error Details

[ERROR] Could not transfer artifact from repo.maven.apache.org: 
        Unsupported or unrecognized SSL message

Root Cause

  • AWF sets HTTP_PROXY and HTTPS_PROXY environment variables
  • Java/Maven do not respect these environment variables
  • Java requires JAVA_TOOL_OPTIONS with explicit -Dhttp.proxyHost and -Dhttps.proxyHost properties
  • AWF does not automatically configure JAVA_TOOL_OPTIONS

Test Results

Project Compile Tests Status
gson N/A FAILED (proxy config)
caffeine N/A FAILED (proxy config)

Overall: FAIL

Required Fix

AWF's docker-manager.ts needs to automatically inject JAVA_TOOL_OPTIONS with proxy configuration when the Squid proxy is enabled, similar to how HTTP_PROXY and HTTPS_PROXY are currently set.

AI generated by Build Test Java

- Cache strlen result to avoid redundant computation
- Add inline comment explaining MAX_TOKENS limit rationale

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 10, 2026

@lpcox Unfortunately I hit an unexpected error while processing your comment. I've automatically reported this to GitHub.

You can ask me to try again later by mentioning me in a new comment.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: 1145c130-58b0-49c7-a67b-7b7412dbf559

Sorry for the inconvenience!

Copilot AI and others added 4 commits February 10, 2026 06:28
- Replace strtok() with strtok_r() to avoid interfering with application code
- Fall back to default token list if AWF_ONE_SHOT_TOKENS parses to zero tokens
- Add warning messages when falling back due to misconfiguration

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

Chroot tests failed Smoke Chroot failed - See logs for details.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

🎬 THE ENDSmoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

@lpcox lpcox merged commit 5d0fe07 into lpcox/one-shot-token-ld-preload Feb 10, 2026
24 of 25 checks passed
@lpcox lpcox deleted the copilot/sub-pr-604 branch February 10, 2026 06:41
@github-actions
Copy link
Contributor

Deno Build Test Results

Project Tests Status
oak 1/1 ✅ PASS
std 1/1 ✅ PASS

Overall: ✅ PASS

All Deno tests completed successfully.

AI generated by Build Test Deno

@github-actions
Copy link
Contributor

Bun Build Test Results

Project Install Tests Status
elysia 1/1 PASS
hono 1/1 PASS

Overall: PASS

All Bun tests completed successfully.

AI generated by Build Test Bun

@github-actions
Copy link
Contributor

Go Build & Test Results ✅

Project Download Tests Status
color 1/1 PASS ✅
env 1/1 PASS ✅
uuid 1/1 PASS ✅

Overall: PASS

All Go projects successfully downloaded dependencies and passed tests.

AI generated by Build Test Go

@github-actions
Copy link
Contributor

Node.js Build Test Results

Project Install Tests Status
clsx PASS PASS
execa PASS PASS
p-limit PASS PASS

Overall: PASS

All Node.js test projects installed dependencies successfully and passed their test suites.

AI generated by Build Test Node.js

@github-actions
Copy link
Contributor

Build Test: Rust - FAILED ❌

Error: Rust toolchain not available in the runner environment.

The workflow requires cargo and rustc to build and test Rust projects, but these tools are not installed.

Missing Tool

  • Tool: Rust toolchain (cargo, rustc)
  • Reason: Cannot build or test Rust projects without cargo/rustc
  • Solution: Install Rust in the workflow or use a runner with Rust pre-installed

Test Status

Project Build Tests Status
fd N/A FAILED - cargo not found
zoxide N/A FAILED - cargo not found

Overall: FAIL

AI generated by Build Test Rust

@github-actions
Copy link
Contributor

Smoke Test Results

Last 2 Merged PRs:

Test Results:

  • ✅ GitHub MCP: Retrieved PR data
  • ✅ Playwright: Page title contains "GitHub"
  • ✅ File Writing: Created test file
  • ✅ Bash Tool: Verified file content

Overall Status: PASS

cc @lpcox

AI generated by Smoke Copilot

@github-actions
Copy link
Contributor

Smoke Test Results: PASS

✅ GitHub MCP: #597 chore(deps): bump the github-actions group, #606 chore(deps): bump the actions group
✅ Playwright: Successfully navigated to github.com (title verified)
✅ File Writing: Created /tmp/gh-aw/agent/smoke-test-claude-21854552113.txt
✅ Bash Tool: File verification successful

Status: PASS - All tests completed successfully.

AI generated by Smoke Claude

@github-actions
Copy link
Contributor

Build Test: Java - FAILED ❌

Test Results

Project Compile Tests Status
gson N/A FAILED
caffeine N/A FAILED

Overall: FAILED ❌

Error Details

Problem: Maven cannot download dependencies through the AWF firewall due to missing Java proxy configuration.

Error Message:

Could not transfer artifact org.apache.maven.plugins:maven-resources-plugin:pom:3.3.1 
from/to central (https://repo.maven.apache.org/maven2): 
Unsupported or unrecognized SSL message

Root Cause: The JAVA_TOOL_OPTIONS environment variable is not being set by the gh-aw workflow runtime, even though the workflow declares network.allowed: java in the configuration.

Expected Behavior: According to AGENTS.md, AWF should automatically configure JAVA_TOOL_OPTIONS with proxy settings when Java is detected:

JAVA_TOOL_OPTIONS="-Dhttp.proxyHost=172.30.0.10 -Dhttp.proxyPort=3128 
                    -Dhttps.proxyHost=172.30.0.10 -Dhttps.proxyPort=3128"

Manual Test: When setting JAVA_TOOL_OPTIONS manually, Maven still fails with SSL errors, suggesting a deeper proxy configuration issue with HTTPS CONNECT tunneling.

Next Steps

This test failure indicates a bug in either:

  1. The gh-aw workflow runtime not setting Java proxy environment variables
  2. The AWF Squid proxy not properly handling Maven's HTTPS connections

The workflow cannot pass until Java proxy configuration is automatically provided by the runtime.

AI generated by Build Test Java

@github-actions github-actions bot mentioned this pull request Feb 10, 2026
Mossaka pushed a commit that referenced this pull request Feb 10, 2026
…ss (#604)

* feat: add one-shot token LD_PRELOAD library for single-use token access

Adds an LD_PRELOAD library that intercepts getenv() calls for sensitive
GitHub token environment variables. On first access, returns the real
value and immediately unsets the variable, preventing subsequent reads
by malicious code.

Protected tokens: COPILOT_GITHUB_TOKEN, GITHUB_TOKEN, GH_TOKEN,
GITHUB_API_TOKEN, GITHUB_PAT, GH_ACCESS_TOKEN

- Add one-shot-token.c with getenv interception logic
- Build library in Dockerfile during image build
- Enable LD_PRELOAD in entrypoint for both container and chroot modes
- Add documentation explaining the mechanism and security properties

* fix: improve one-shot token library copy robustness in chroot mode (#606)

* Initial plan

* fix: improve one-shot token library copy with better error handling

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

* Update containers/agent/one-shot-token/README.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update containers/agent/one-shot-token/README.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix: use pthread_once for thread-safe getenv initialization (#609)

* Initial plan

* fix: use pthread_once for thread-safe getenv initialization

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

* chore: complete thread safety fix

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

* test: add integration tests for one-shot token LD_PRELOAD library (#608)

* Initial plan

* test: add integration tests for one-shot token LD_PRELOAD library

Add comprehensive integration tests that verify the one-shot token protection
mechanism works correctly in both container and chroot modes. Tests verify:

- Protected tokens (GITHUB_TOKEN, COPILOT_GITHUB_TOKEN, OPENAI_API_KEY) can be read once
- Subsequent reads return empty/null (token has been cleared)
- Non-sensitive environment variables are not affected
- Multiple tokens are handled independently
- Behavior works with both shell (printenv) and programmatic (Python getenv) access
- Edge cases (empty values, nonexistent tokens, special characters) are handled

Tests address feedback from PR #604 review requesting integration tests for
the one-shot token feature to prevent regressions.

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

* fix: preserve secure_getenv semantics in one-shot token interposer (#610)

* Initial plan

* fix: implement proper secure_getenv with dlsym fallback

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

* fix: add thread safety to secure_getenv initialization

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: Landon Cox <landon.cox@microsoft.com>

* feat: add runtime configuration for one-shot token protection via AWF_ONE_SHOT_TOKENS (#607)

* Initial plan

* feat: add runtime configuration for one-shot token list via AWF_ONE_SHOT_TOKENS

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

* fix: address code review feedback for one-shot token library

- Make initialization thread-safe using existing mutex
- Add cleanup of allocated tokens on memory allocation failure
- Use isspace() for comprehensive whitespace trimming (handles newlines, tabs, etc.)

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

* fix: resolve race condition and buffer underflow in token parsing

- Fix potential buffer underflow when trimming empty strings
- Fix race condition by keeping mutex held during get_token_index() call
- Ensure thread-safe access to token list during lookup

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

* refactor: optimize strlen usage and add MAX_TOKENS documentation

- Cache strlen result to avoid redundant computation
- Add inline comment explaining MAX_TOKENS limit rationale

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

* style: improve comment formatting for MAX_TOKENS

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

* fix: use strtok_r and fallback to defaults for empty token list

- Replace strtok() with strtok_r() to avoid interfering with application code
- Fall back to default token list if AWF_ONE_SHOT_TOKENS parses to zero tokens
- Add warning messages when falling back due to misconfiguration

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

* docs: update README with fallback behavior and strtok_r details

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

* refactor: explicitly reset num_tokens in fallback path for clarity

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

* docs: clarify defensive programming intent in num_tokens reset

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: Landon Cox <landon.cox@microsoft.com>

* fix: add missing secure_getenv interposer initialization (#619)

* Initial plan

* fix: add missing secure_getenv declarations and initialization

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

* chore: remove build artifacts from git

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

* docs: update progress - fix complete

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

* chore: remove test files from git

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

---------

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants