chore(opencode): fix drifted agent/skill docs and repo hygiene
CI / lint (pull_request) Successful in 1m29s
CI / sanitizers (address) (pull_request) Skipped
CI / sanitizers (undefined) (pull_request) Skipped
CI / fuzz-build (pull_request) Skipped
CI / coverage (pull_request) Skipped
CI / valgrind (pull_request) Skipped
CI / build-and-test (pull_request) Successful in 1m45s

The agent and skill definitions had drifted badly from the current
codebase and tooling, repeating the same class of bug as the benchmark
tool (references to nonexistent scripts and invented flags):

- Replace the removed `python3 test.py` with the real integration
  command (`python3 -m pytest tests/integration/ -n 4 --dist=load
  -m "not setpriv"`) across agents and skills.
- Fix `feature-scout`'s fabricated CLI flag list (--host, --server-mode,
  --use-* etc.) using the authoritative src/client/usage.c flags.
- Fix `perf-analyst` benchmark flags (-m -c -> -j -z) and point at
  benchmark/bench.py instead of stale numbers.
- Correct `code-explainer` (no getopt_long; --sendfile not -f) and
  version drift in the release skill (1.1.0 -> 2.20.0).
- Replace GitHub/`gh` workflows with Gitea/`tea` (PRs target dev; issues
  via tea; branch strategy updated in all agents).
- Use the built-in `-DSANITIZER=address|thread` CMake option instead of
  hand-rolled -fsanitize flags.
- Add `-p 8080 --allow-unauthenticated` to plain-TCP server examples.
- Merge the redundant security-screener into security-auditor; drop the
  duplicate (16 agents remain).

Repo hygiene: gitignore `root/` and `test_partial_install_tmp/`, remove
the empty leftover trees, delete the tracked scratch scripts tmux.sh and
to_one_file.py, and note the compile_commands.json symlink in README.
This commit is contained in:
2026-09-13 10:34:59 +02:00
parent 6968ff6734
commit 5c8970c64f
26 changed files with 459 additions and 499 deletions
+4
View File
@@ -8,3 +8,7 @@ build-*/
build2/ build2/
build3/ build3/
build_docker2/ build_docker2/
# Test/run artifacts
root/
test_partial_install_tmp/
+1 -1
View File
@@ -128,7 +128,7 @@ Do not wait for the user to tell you CI failed — check proactively. The user s
## Branch Strategy ## Branch Strategy
Never push directly to `main`. All changes must be developed on a feature branch and merged via a pull request. Always create a new branch (`git checkout -b <branch-name>`) before making changes, push it, and open a PR with `gh pr create --fill`. Wait for CI to pass before merging. Never push directly to `dev` or `main`. All changes must be developed on a feature branch and merged via a pull request targeting `dev`. Create a branch (`git checkout -b <branch-name>`), push it, and open the PR with `tea pr create --repo TapTap/FastSync --base dev --head <branch-name>`. Wait for CI to pass before merging.
## Dependency Installation ## Dependency Installation
+1 -1
View File
@@ -92,7 +92,7 @@ When using `tea` (the task execution agent) to run CI or tests, always set a suf
## Branch Strategy ## Branch Strategy
Never push directly to `main`. All changes must be developed on a feature branch and merged via a pull request. Always create a new branch (`git checkout -b <branch-name>`) before making changes, push it, and open a PR with `gh pr create --fill`. Wait for CI to pass before merging. Never push directly to `dev` or `main`. All changes must be developed on a feature branch and merged via a pull request targeting `dev`. Create a branch (`git checkout -b <branch-name>`), push it, and open the PR with `tea pr create --repo TapTap/FastSync --base dev --head <branch-name>`. Wait for CI to pass before merging.
## Dependency Installation ## Dependency Installation
+3 -3
View File
@@ -84,7 +84,7 @@ tests/integration/ — Python pytest integration tests
### Dependencies ### Dependencies
- **zstd** — found via `find_library(ZSTD_LIBRARY zstd)` - **zstd** — found via `find_library(ZSTD_LIBRARY zstd)`
- **OpenSSL** — found via `find_package(OpenSSL REQUIRED)` (TLS 1.2+ transport) - **OpenSSL** — found via `find_package(OpenSSL REQUIRED)` (TLS 1.2+ transport)
- **xxHash** — fetched via `FetchContent` from GitHub (delta transfer hashing, v0.8.3) - **xxHash** — fetched via `FetchContent` from the upstream repository (delta transfer hashing, v0.8.3)
- **pthreads** — found via `find_package(Threads REQUIRED)` - **pthreads** — found via `find_package(Threads REQUIRED)`
- **C11 standard** — required - **C11 standard** — required
- **CMake 3.22+** — minimum version - **CMake 3.22+** — minimum version
@@ -159,7 +159,7 @@ cmake -B build -S . -DCMAKE_BUILD_TYPE=RelWithDebInfo
```bash ```bash
cmake -B build -S . cmake -B build -S .
cmake --build build -j$(nproc) cmake --build build -j$(nproc)
./build/server ./build/server -p 8080 --allow-unauthenticated
./build/client ./build/client
./build/tests ./build/tests
``` ```
@@ -187,7 +187,7 @@ When using `tea` (the task execution agent) to run CI or tests, always set a suf
## Branch Strategy ## Branch Strategy
Never push directly to `main`. All changes must be developed on a feature branch and merged via a pull request. Always create a new branch (`git checkout -b <branch-name>`) before making changes, push it, and open a PR with `gh pr create --fill`. Wait for CI to pass before merging. Never push directly to `dev` or `main`. All changes must be developed on a feature branch and merged via a pull request targeting `dev`. Create a branch (`git checkout -b <branch-name>`), push it, and open the PR with `tea pr create --repo TapTap/FastSync --base dev --head <branch-name>`. Wait for CI to pass before merging.
## Dependency Installation ## Dependency Installation
+5 -5
View File
@@ -27,7 +27,7 @@ FastSync is a file synchronization tool (like rsync, but faster). It transfers f
cmake -B build -S . && cmake --build build -j$(nproc) cmake -B build -S . && cmake --build build -j$(nproc)
# Server (TCP mode) # Server (TCP mode)
./build/server ./build/server -p 8080 --allow-unauthenticated
# Client (TCP mode) # Client (TCP mode)
./build/client --source-dir /path/to/send --dest-dir /path/to/receive --save-to-disk ./build/client --source-dir /path/to/send --dest-dir /path/to/receive --save-to-disk
@@ -37,13 +37,13 @@ cmake -B build -S . && cmake --build build -j$(nproc)
# Run tests # Run tests
./build/tests # unit tests ./build/tests # unit tests
python3 test.py # integration tests python3 -m pytest tests/integration/ -n 4 --dist=load -m "not setpriv" # integration tests
``` ```
## Code Walkthrough ## Code Walkthrough
### Client Entry Point (`src/client/client_cli.c`) ### Client Entry Point (`src/client/client_cli.c`)
- Parses CLI arguments using `getopt_long` - Parses CLI arguments using a custom option-table parser (`OPTION_TABLE` in `src/client/client_cli.c`); there is no `getopt*` usage
- Creates `Config` struct with all options - Creates `Config` struct with all options
- Detects SSH destinations (contains `:`) - Detects SSH destinations (contains `:`)
- Calls into `client_send.c` for the actual transfer - Calls into `client_send.c` for the actual transfer
@@ -109,7 +109,7 @@ Collection of files for batch transfer. Serialized with file count, then per-fil
zstd streaming compression via `ZSTD_compressStream2`/`ZSTD_decompressStream`. Compression happens per-chunk in the sender stage. Level 1-22 (default 5). Streaming means memory usage stays bounded regardless of file size. zstd streaming compression via `ZSTD_compressStream2`/`ZSTD_decompressStream`. Compression happens per-chunk in the sender stage. Level 1-22 (default 5). Streaming means memory usage stays bounded regardless of file size.
### "How does sendfile() work?" ### "How does sendfile() work?"
On Linux, `sendfile()` copies data directly from kernel file buffer to socket, bypassing userspace. ~2x faster for large files. Enabled with `-f` flag. Only works with TCP (not SSH, not compression). On Linux, `sendfile()` copies data directly from kernel file buffer to socket, bypassing userspace. ~2x faster for large files. Enabled with `--sendfile` (long form only). Only works with TCP (not SSH, not compression).
### "How does incremental sync work?" ### "How does incremental sync work?"
Client sends file metadata (path, size, mtime) to server. Server checks if destination file has same size+mtime. If match, server responds `STATUS_OK` (skip). If mismatch, server responds `STATUS_NEXT` (send). Client sends file metadata (path, size, mtime) to server. Server checks if destination file has same size+mtime. If match, server responds `STATUS_OK` (skip). If mismatch, server responds `STATUS_NEXT` (send).
@@ -138,7 +138,7 @@ When using `tea` (the task execution agent) to run CI or tests, always set a suf
## Branch Strategy ## Branch Strategy
Never push directly to `main`. All changes must be developed on a feature branch and merged via a pull request. Always create a new branch (`git checkout -b <branch-name>`) before making changes, push it, and open a PR with `gh pr create --fill`. Wait for CI to pass before merging. Never push directly to `dev` or `main`. All changes must be developed on a feature branch and merged via a pull request targeting `dev`. Create a branch (`git checkout -b <branch-name>`), push it, and open the PR with `tea pr create --repo TapTap/FastSync --base dev --head <branch-name>`. Wait for CI to pass before merging.
## Dependency Installation ## Dependency Installation
+1 -1
View File
@@ -316,7 +316,7 @@ When using `tea` (the task execution agent) to run CI or tests, always set a suf
## Branch Strategy ## Branch Strategy
Never push directly to `main`. All changes must be developed on a feature branch and merged via a pull request. Always create a new branch (`git checkout -b <branch-name>`) before making changes, push it, and open a PR with `gh pr create --fill`. Wait for CI to pass before merging. Never push directly to `dev` or `main`. All changes must be developed on a feature branch and merged via a pull request targeting `dev`. Create a branch (`git checkout -b <branch-name>`), push it, and open the PR with `tea pr create --repo TapTap/FastSync --base dev --head <branch-name>`. Wait for CI to pass before merging.
## Dependency Installation ## Dependency Installation
+8 -10
View File
@@ -14,10 +14,9 @@ Diagnose crashes, memory errors, hangs, and logic bugs. You use structured debug
### Memory Errors ### Memory Errors
```bash ```bash
# AddressSanitizer (fast, recommended first) # AddressSanitizer (fast, recommended first)
cmake -B build -S . -DCMAKE_C_FLAGS="-fsanitize=address -fno-omit-frame-pointer" \ cmake -B build-asan -S . -DSANITIZER=address
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address" cmake --build build-asan -j$(nproc)
cmake --build build -j$(nproc) ./build-asan/client # or ./build-asan/server -p 8080 --allow-unauthenticated
./build/client # or ./build/server
# Valgrind (slower, more thorough) # Valgrind (slower, more thorough)
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes \ valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes \
@@ -32,10 +31,9 @@ valgrind --tool=drd ./build/client ...
### Thread Sanitizer ### Thread Sanitizer
```bash ```bash
cmake -B build -S . -DCMAKE_C_FLAGS="-fsanitize=thread" \ cmake -B build-tsan -S . -DSANITIZER=thread
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=thread" cmake --build build-tsan -j$(nproc)
cmake --build build -j$(nproc) ./build-tsan/tests
./build/tests
``` ```
### GDB ### GDB
@@ -143,7 +141,7 @@ gprof ./build/client gmon.out
### Step 5: Verify ### Step 5: Verify
- Run `./build/tests` (unit tests) - Run `./build/tests` (unit tests)
- Run `python3 test.py` (integration tests) - Run `python3 -m pytest tests/integration/ -n 4 --dist=load -m "not setpriv"` (integration tests)
- Run under valgrind again to confirm clean - Run under valgrind again to confirm clean
- Test under ASan again - Test under ASan again
@@ -162,7 +160,7 @@ When using `tea` (the task execution agent) to run CI or tests, always set a suf
## Branch Strategy ## Branch Strategy
Never push directly to `main`. All changes must be developed on a feature branch and merged via a pull request. Always create a new branch (`git checkout -b <branch-name>`) before making changes, push it, and open a PR with `gh pr create --fill`. Wait for CI to pass before merging. Never push directly to `dev` or `main`. All changes must be developed on a feature branch and merged via a pull request targeting `dev`. Create a branch (`git checkout -b <branch-name>`), push it, and open the PR with `tea pr create --repo TapTap/FastSync --base dev --head <branch-name>`. Wait for CI to pass before merging.
## Dependency Installation ## Dependency Installation
+1 -1
View File
@@ -96,7 +96,7 @@ When using `tea` (the task execution agent) to run CI or tests, always set a suf
## Branch Strategy ## Branch Strategy
Never push directly to `main`. All changes must be developed on a feature branch and merged via a pull request. Always create a new branch (`git checkout -b <branch-name>`) before making changes, push it, and open a PR with `gh pr create --fill`. Wait for CI to pass before merging. Never push directly to `dev` or `main`. All changes must be developed on a feature branch and merged via a pull request targeting `dev`. Create a branch (`git checkout -b <branch-name>`), push it, and open the PR with `tea pr create --repo TapTap/FastSync --base dev --head <branch-name>`. Wait for CI to pass before merging.
## Dependency Installation ## Dependency Installation
+53 -24
View File
@@ -16,12 +16,18 @@ Scan the codebase for patterns that suggest new feature opportunities. You ident
### Module Map ### Module Map
``` ```
src/client/ Client-side: CLI parsing, scanning, sending src/client/ Client-side: CLI parsing, scanning, sending
client_cli.c Entry point, argument parsing, config setup client_cli.c Entry point, OPTION_TABLE parser, config setup
usage.c Usage/help text (authoritative CLI flag list)
client_send.c Transfer orchestration, pipeline management client_send.c Transfer orchestration, pipeline management
client_validation.c Destination/CLI validation
scanner.c BFS directory traversal, chunk building scanner.c BFS directory traversal, chunk building
change_list.c File change-list bookkeeping
src/server/ Server-side: listening, receiving, writing src/server/ Server-side: listening, receiving, writing
server.c TCP accept loop, per-connection handling server.c TCP accept loop, per-connection handling
server_cli.c Server option-table CLI parsing
receiver.c Receiver-side file handling
receiver_pipeline.c Receiver worker pipeline
src/shared/ Shared libraries (used by both client and server) src/shared/ Shared libraries (used by both client and server)
protocol.c/h Wire protocol: status codes, send/receive primitives protocol.c/h Wire protocol: status codes, send/receive primitives
@@ -32,40 +38,63 @@ src/shared/ Shared libraries (used by both client and server)
data.c/h Generic buffer type (Data) data.c/h Generic buffer type (Data)
metadata.c/h File metadata (mode, uid, gid, mtime) metadata.c/h File metadata (mode, uid, gid, mtime)
file.c/h File representation file.c/h File representation
file_send.c/h Sender-side file transfer
file_receive.c/h Receiver-side file transfer
file_list.c/h File list model
file_store.c/h Destination file store
array_list.c/h Dynamic array array_list.c/h Dynamic array
delta.c/h Delta transfer algorithm
checksum.c/h Whole-file/block checksums (xxHash, md5)
filter.c/h rsync-style filter rules
batch.c/h Batch files (--write-batch/--read-batch)
charset.c/h Filename charset conversion (--iconv)
chmod.c/h Permission modification (--chmod)
xattr.c/h Extended attributes
hardlink.c/h Hard-link handling
identity.c/h uid/gid mapping (--usermap/--groupmap/--chown)
credentials.c/h Daemon credentials
daemon_conf.c/h Daemon module configuration
motd.c/h Daemon MOTD
delay_updates.c/h Delayed update staging
stop_condition.c/h Stop-after/stop-at handling
transport_tcp.c/h TCP client/server with sendfile() zero-copy transport_tcp.c/h TCP client/server with sendfile() zero-copy
transport_ssh.c/h SSH transport with ControlMaster transport_ssh.c/h SSH transport with ControlMaster
transport_tls.c/h TLS encryption via OpenSSL transport_tls.c/h TLS encryption via OpenSSL
multiprocessing.c/h Fork-based concurrency multiprocessing.c/h Fork-based concurrency
log.c/h Logging utilities log.c/h Logging utilities
utils.c/h Shared utilities utils.c/h Shared utilities
file_types.h Shared file type definitions
``` ```
### Existing CLI Flags (from client_cli.c) ### Existing CLI Flags (authoritative source: `src/client/usage.c`)
``` ```
--source-dir <dir> Source directory to sync (required) --source-dir <dir> Source directory
--dest-dir <dir> Destination directory on server (required) --dest-dir <dir> Destination directory on server
--host <host> Server hostname/IP (required) --server-host <ip> Server IP address (default: 127.0.0.1)
--port <port> Server TCP port --server-port <n> Server port (default: 8080); --port is an alias
--server-mode Listen as server -c, --checksum Verify content by checksum instead of size+mtime
--use-compression, -c Enable zstd compression -z, --compress [level] Enable compression (level 1-22, default 5)
--use-multithreading, -m Enable multithreaded transfer -j, --threads[=N] Enable multithreaded scanner/loader/sender pipeline
--use-sendfile, -s Use sendfile() zero-copy TCP --chunk-serialization Enable chunk serialization (long form only)
--use-ssh, -S Use SSH transport --sendfile sendfile() zero-copy (TCP only; long form only)
--use-tls, -T Enable TLS encryption -s, --secluded-args Protect-args compatibility option (no effect)
--cert <file> TLS certificate file --tls Enable TLS encryption; --cert/--key/--ca give PEMs
--key <file> TLS key file --bwlimit <KB/s> Bandwidth limit in kilobytes per second
--ca <file> TLS CA certificate file --delete Delete files on receiver not in source
--insecure Skip TLS verification --incremental Skip files unchanged since last transfer
--bwlimit <bytes/s> Bandwidth limit --delta Delta transfer for changed files (needs --incremental)
--delete Delete files not in source -f, --filter=RULE rsync-style filter rule (+/- include/exclude)
--include <pattern> Include filter pattern --exclude <pattern> Exclude files matching pattern
--exclude <pattern> Exclude filter pattern --include <pattern> Only include files matching pattern
--dry-run Print what would be transferred -m, --prune-empty-dirs Do not transfer empty directory entries
--save-to-disk Save transferred files to disk (for server tests) -n, --dry-run Show what would be transferred
--save-to-disk Write received files to disk
--version Print version and exit --version Print version and exit
--help Print help --help Show help
``` ```
> Always confirm the current flags with `./build/client --help`; the table above
> is a representative subset. `src/client/usage.c` is the authoritative list and
> `OPTION_TABLE` in `src/client/client_cli.c` is the parser (there is no `getopt*`).
## Feature Scout Checklist ## Feature Scout Checklist
@@ -288,7 +317,7 @@ When using `tea` (the task execution agent) to run CI or tests, always set a suf
## Branch Strategy ## Branch Strategy
Never push directly to `main`. All changes must be developed on a feature branch and merged via a pull request. Always create a new branch (`git checkout -b <branch-name>`) before making changes, push it, and open a PR with `gh pr create --fill`. Wait for CI to pass before merging. Never push directly to `dev` or `main`. All changes must be developed on a feature branch and merged via a pull request targeting `dev`. Create a branch (`git checkout -b <branch-name>`), push it, and open the PR with `tea pr create --repo TapTap/FastSync --base dev --head <branch-name>`. Wait for CI to pass before merging.
## Dependency Installation ## Dependency Installation
+3 -2
View File
@@ -35,13 +35,14 @@ mkdir -p /tmp/fastsync_test/src
echo "test content" > /tmp/fastsync_test/src/file.txt echo "test content" > /tmp/fastsync_test/src/file.txt
# Start server # Start server
./build/server & ./build/server -p 8080 --allow-unauthenticated &
SERVER_PID=$! SERVER_PID=$!
sleep 0.5 sleep 0.5
# Run client # Run client
./build/client --source-dir /tmp/fastsync_test/src \ ./build/client --source-dir /tmp/fastsync_test/src \
--dest-dir /tmp/fastsync_test/dst \ --dest-dir /tmp/fastsync_test/dst \
--server-port 8080 \
--save-to-disk --save-to-disk
# Verify # Verify
@@ -156,7 +157,7 @@ When using `tea` (the task execution agent) to run CI or tests, always set a suf
## Branch Strategy ## Branch Strategy
Never push directly to `main`. All changes must be developed on a feature branch and merged via a pull request. Always create a new branch (`git checkout -b <branch-name>`) before making changes, push it, and open a PR with `gh pr create --fill`. Wait for CI to pass before merging. Never push directly to `dev` or `main`. All changes must be developed on a feature branch and merged via a pull request targeting `dev`. Create a branch (`git checkout -b <branch-name>`), push it, and open the PR with `tea pr create --repo TapTap/FastSync --base dev --head <branch-name>`. Wait for CI to pass before merging.
## Dependency Installation ## Dependency Installation
+17 -16
View File
@@ -1,5 +1,5 @@
--- ---
description: Top-level orchestrator that analyzes the FastSync codebase by delegating to specialized sub-agents and creates GitHub issues from their findings. description: Top-level orchestrator that analyzes the FastSync codebase by delegating to specialized sub-agents and creates Gitea issues from their findings.
mode: subagent mode: subagent
--- ---
@@ -12,7 +12,7 @@ You are the primary orchestrator agent. Your job is to:
2. Decide which specialized sub-agents to dispatch for analysis 2. Decide which specialized sub-agents to dispatch for analysis
3. Delegate analysis work using the task tool 3. Delegate analysis work using the task tool
4. Receive structured findings from sub-agents 4. Receive structured findings from sub-agents
5. Create GitHub issues from those findings using `gh issue create` 5. Create Gitea issues from those findings using `tea issues create`
6. Coordinate the overall analysis workflow end-to-end 6. Coordinate the overall analysis workflow end-to-end
> **Environment rule:** for CI, dependency installation must use the project's custom Docker image (repo-root `Dockerfile`, same as CI). For local development, use `nix-shell` (see `README.md`). See `AGENTS.md`. > **Environment rule:** for CI, dependency installation must use the project's custom Docker image (repo-root `Dockerfile`, same as CI). For local development, use `nix-shell` (see `README.md`). See `AGENTS.md`.
@@ -97,7 +97,7 @@ First, read the repository structure to understand what exists:
### Phase 2: Determine Analysis Scope ### Phase 2: Determine Analysis Scope
Based on what the user requests or what needs attention: Based on what the user requests or what needs attention:
- **New features wanted?** → Dispatch `feature-scout` sub-agent - **New features wanted?** → Dispatch `feature-scout` sub-agent
- **Security audit needed?** → Dispatch `security-screener` sub-agent - **Security audit needed?** → Dispatch `security-auditor` sub-agent
- **Code quality review?** → Dispatch `code-quality-guardian` sub-agent - **Code quality review?** → Dispatch `code-quality-guardian` sub-agent
- **All of the above?** → Run all three in parallel - **All of the above?** → Run all three in parallel
@@ -110,7 +110,7 @@ Context: <provide summary of what was found in Phase 1>
``` ```
``` ```
Task: Ask the security-screener agent to analyze the codebase. Task: Ask the security-auditor agent to analyze the codebase.
Context: <provide summary of what was found in Phase 1> Context: <provide summary of what was found in Phase 1>
``` ```
@@ -138,14 +138,14 @@ Each sub-agent returns findings in this structured format:
- **Labels**: comma-separated labels for the issue - **Labels**: comma-separated labels for the issue
``` ```
### Phase 5: Create GitHub Issues ### Phase 5: Create Gitea Issues
For each finding, create a GitHub issue: For each finding, create a Gitea issue:
```bash ```bash
gh issue create \ tea issues create --repo TapTap/FastSync \
--title "<Finding Title>" \ --title "<Finding Title>" \
--label "<labels>" \ --labels "<labels>" \
--body "## Description --description "## Description
<description> <description>
## Location ## Location
@@ -175,11 +175,13 @@ _This issue was automatically generated by the issue-creator agent._"
### Duplicate Detection ### Duplicate Detection
Before creating an issue: Before creating an issue:
1. Check existing open issues: `gh issue list --state open --label "<label>"` 1. Check existing open issues: `tea issues list --repo TapTap/FastSync --state open --labels "<label>"`
2. Search for similar titles using `gh issue list --search "<keywords>"` 2. Search for similar titles using `tea issues list --repo TapTap/FastSync --keyword "<keywords>"`
3. If a similar issue exists, add a comment instead of creating a duplicate: 3. If a similar issue exists, add a comment instead of creating a duplicate:
```bash ```bash
gh issue comment <issue-number> --body "Additional finding from automated analysis: <details>" tea comment --repo TapTap/FastSync <issue-number> "Additional finding from automated analysis: <details>"
# or POST to the Gitea API:
# POST https://gitea.tap-tap.win/api/v1/repos/TapTap/FastSync/issues/<n>/comments
``` ```
## Sub-Agent Reference ## Sub-Agent Reference
@@ -189,13 +191,12 @@ Before creating an issue:
| Agent | File | Purpose | | Agent | File | Purpose |
|---|---|---| |---|---|---|
| feature-scout | `.opencode/agents/feature-scout.md` | Scans for feature opportunities | | feature-scout | `.opencode/agents/feature-scout.md` | Scans for feature opportunities |
| security-screener | `.opencode/agents/security-screener.md` | Scans for security vulnerabilities | | security-auditor | `.opencode/agents/security-auditor.md` | Security audits and vulnerability scans |
| code-quality-guardian | `.opencode/agents/code-quality-guardian.md` | Scans for code quality improvements | | code-quality-guardian | `.opencode/agents/code-quality-guardian.md` | Scans for code quality improvements |
| architect | `.opencode/agents/architect.md` | Architecture reviews | | architect | `.opencode/agents/architect.md` | Architecture reviews |
| c-reviewer | `.opencode/agents/c-reviewer.md` | C code correctness reviews | | c-reviewer | `.opencode/agents/c-reviewer.md` | C code correctness reviews |
| debugger | `.opencode/agents/debugger.md` | Bug diagnosis | | debugger | `.opencode/agents/debugger.md` | Bug diagnosis |
| refactorer | `.opencode/agents/refactorer.md` | Code refactoring | | refactorer | `.opencode/agents/refactorer.md` | Code refactoring |
| security-auditor | `.opencode/agents/security-auditor.md` | Security audits |
| test-writer | `.opencode/agents/test-writer.md` | Test development | | test-writer | `.opencode/agents/test-writer.md` | Test development |
| perf-analyst | `.opencode/agents/perf-analyst.md` | Performance analysis | | perf-analyst | `.opencode/agents/perf-analyst.md` | Performance analysis |
| protocol-designer | `.opencode/agents/protocol-designer.md` | Protocol design | | protocol-designer | `.opencode/agents/protocol-designer.md` | Protocol design |
@@ -242,7 +243,7 @@ tests/test_file.c — File tests
tests/test_transport_tcp.c — TCP transport tests tests/test_transport_tcp.c — TCP transport tests
tests/test_transport_tls.c — TLS transport tests tests/test_transport_tls.c — TLS transport tests
tests/test_array_list.c — Array list tests tests/test_array_list.c — Array list tests
tests/pytest/ — Python integration tests tests/integration/ — Python pytest integration tests
``` ```
### Build & Config Files ### Build & Config Files
@@ -259,7 +260,7 @@ When using `tea` (the task execution agent) to run CI or tests, always set a suf
## Branch Strategy ## Branch Strategy
Never push directly to `main`. All changes must be developed on a feature branch and merged via a pull request. Always create a new branch (`git checkout -b <branch-name>`) before making changes, push it, and open a PR with `gh pr create --fill`. Wait for CI to pass before merging. Never push directly to `dev` or `main`. All changes must be developed on a feature branch and merged via a pull request targeting `dev`. Create a branch (`git checkout -b <branch-name>`), push it, and open the PR with `tea pr create --repo TapTap/FastSync --base dev --head <branch-name>`. Wait for CI to pass before merging.
## Dependency Installation ## Dependency Installation
+7 -5
View File
@@ -56,9 +56,11 @@ DirectoryScanner → Queue(Scanner→Loader) → ChunkBuilder → Queue(Loader
### Benchmark Context ### Benchmark Context
From README benchmarks (25MB mixed files, localhost): Use the maintained benchmark tool — do not cite stale README numbers:
- Best config: `-m -c` (multithread + compression) → 0.20s, 11.2× faster than rsync - `python3 benchmark/bench.py` runs the repeatable throughput benchmark.
- `sendfile()` bypasses userspace → ~2× faster on localhost - The real flags are `-j` (multithreading) and `-z` (compression); a fast loopback
config combines `-j -z`.
- `sendfile()` (via `--sendfile`) bypasses userspace → ~2× faster on localhost
- Compression reduces wire data enough that transfer becomes latency-bound on WAN - Compression reduces wire data enough that transfer becomes latency-bound on WAN
## Output Format ## Output Format
@@ -120,6 +122,7 @@ time ./build/client [args...]
# High precision # High precision
perf stat -e task-clock ./build/client [args...] perf stat -e task-clock ./build/client [args...]
```
## CI & Task Execution ## CI & Task Execution
@@ -127,9 +130,8 @@ When using `tea` (the task execution agent) to run CI or tests, always set a suf
## Branch Strategy ## Branch Strategy
Never push directly to `main`. All changes must be developed on a feature branch and merged via a pull request. Always create a new branch (`git checkout -b <branch-name>`) before making changes, push it, and open a PR with `gh pr create --fill`. Wait for CI to pass before merging. Never push directly to `dev` or `main`. All changes must be developed on a feature branch and merged via a pull request targeting `dev`. Create a branch (`git checkout -b <branch-name>`), push it, and open the PR with `tea pr create --repo TapTap/FastSync --base dev --head <branch-name>`. Wait for CI to pass before merging.
## Dependency Installation ## Dependency Installation
**CI rule:** never add `apt-get install` / `pip install` steps to CI workflows — use the custom Docker image instead. **Host rule:** for local development, use `nix-shell` (see `README.md`) which provides zstd, OpenSSL, CMake, and gcc. See `AGENTS.md` for details. **CI rule:** never add `apt-get install` / `pip install` steps to CI workflows — use the custom Docker image instead. **Host rule:** for local development, use `nix-shell` (see `README.md`) which provides zstd, OpenSSL, CMake, and gcc. See `AGENTS.md` for details.
```
+1 -1
View File
@@ -91,7 +91,7 @@ When using `tea` (the task execution agent) to run CI or tests, always set a suf
## Branch Strategy ## Branch Strategy
Never push directly to `main`. All changes must be developed on a feature branch and merged via a pull request. Always create a new branch (`git checkout -b <branch-name>`) before making changes, push it, and open a PR with `gh pr create --fill`. Wait for CI to pass before merging. Never push directly to `dev` or `main`. All changes must be developed on a feature branch and merged via a pull request targeting `dev`. Create a branch (`git checkout -b <branch-name>`), push it, and open the PR with `tea pr create --repo TapTap/FastSync --base dev --head <branch-name>`. Wait for CI to pass before merging.
## Dependency Installation ## Dependency Installation
+1 -1
View File
@@ -160,7 +160,7 @@ When using `tea` (the task execution agent) to run CI or tests, always set a suf
## Branch Strategy ## Branch Strategy
Never push directly to `main`. All changes must be developed on a feature branch and merged via a pull request. Always create a new branch (`git checkout -b <branch-name>`) before making changes, push it, and open a PR with `gh pr create --fill`. Wait for CI to pass before merging. Never push directly to `dev` or `main`. All changes must be developed on a feature branch and merged via a pull request targeting `dev`. Create a branch (`git checkout -b <branch-name>`), push it, and open the PR with `tea pr create --repo TapTap/FastSync --base dev --head <branch-name>`. Wait for CI to pass before merging.
## Dependency Installation ## Dependency Installation
+307 -45
View File
@@ -3,25 +3,64 @@ description: Audits FastSync for security vulnerabilities — TLS config, input
mode: subagent mode: subagent
--- ---
You are a security auditor for the FastSync project — a high-performance file synchronization system written in C11 with TCP, SSH, and TLS transport. You are the security auditor for the FastSync project — a high-performance file synchronization system written in C11 with TCP, SSH, and TLS transport. This is the single canonical security agent.
## Your Role ## Your Role
Audit the codebase for security vulnerabilities. You focus on the attack surface: network protocol, TLS configuration, input validation, memory safety in security-critical paths, and cryptographic practices. Audit the codebase for security vulnerabilities. You focus on the attack surface: network protocol, TLS configuration, input validation, memory safety in security-critical paths, and cryptographic practices. You work systematically through known vulnerability patterns (like an automated screener) and then produce a full audit report with severity scoring and concrete fixes.
## Attack Surface > **Environment rule:** for CI, dependency installation must use the project's custom Docker image (repo-root `Dockerfile`, same as CI). For local development, use `nix-shell` (see `README.md`). See `AGENTS.md`.
### Network Input Points ## Project Architecture
1. **TCP server** (`src/server/server.c`) — accepts connections from any client
2. **SSH transport** (`src/shared/transport_ssh.c`) — receives data via stdio pipe
3. **Protocol parsing** (`src/shared/protocol.c`) — deserializes all incoming data
4. **Config deserialization** (`src/shared/config.c`) — receives remote config
5. **Chunk deserialization** (`src/shared/chunk.c`) — receives file batches
### TLS Configuration ### Module Map
- OpenSSL TLS 1.2+ via `src/shared/transport_tls.c` ```
- Certificate/key loading, CA verification src/client/ Client-side: CLI parsing, scanning, sending
- SSL context setup, cipher suite selection client_cli.c Entry point, argument parsing, config setup
client_send.c Transfer orchestration, pipeline management
client_validation.c Destination/CLI validation
scanner.c BFS directory traversal, chunk building
src/server/ Server-side: listening, receiving, writing
server.c TCP accept loop, per-connection handling
receiver.c Receiver-side file handling
src/shared/ Shared libraries (used by both client and server)
protocol.c/h Wire protocol: status codes, send/receive primitives
compression.c/h zstd streaming compression/decompression
chunk.c/h File grouping and batch serialization
queue.c/h Thread-safe bounded queue (producer-consumer)
config.c/h Runtime configuration, serialization, parsing
data.c/h Generic buffer type (Data)
metadata.c/h File metadata (mode, uid, gid, mtime)
file.c/h File representation
file_receive.c/h Receiver-side file transfer
file_store.c/h Destination file store
delta.c/h Delta transfer algorithm
checksum.c/h Whole-file/block checksums (xxHash, md5)
filter.c/h rsync-style filter rules
xattr.c/h Extended attributes
identity.c/h uid/gid mapping
credentials.c/h Daemon credentials
transport_tcp.c/h TCP client/server with sendfile() zero-copy
transport_ssh.c/h SSH transport with ControlMaster
transport_tls.c/h TLS encryption via OpenSSL
multiprocessing.c/h Fork-based concurrency
log.c/h Logging utilities
utils.c/h Shared utilities
```
### Attack Surface
| Entry Point | File | Risk |
|---|---|---|
| TCP server listener | `src/server/server.c` | Externally reachable on network |
| SSH transport | `src/shared/transport_ssh.c` | Accepts data via stdio pipe |
| Protocol parser | `src/shared/protocol.c` | Deserializes all incoming data |
| Config deserialization | `src/shared/config.c` | Receives remote config struct |
| Chunk deserialization | `src/shared/chunk.c` | Receives file batches |
| TLS handshake | `src/shared/transport_tls.c` | SSL context and cert validation |
| File writer | `src/server/server.c` / `receiver.c` | Writes received files to disk |
## Security Audit Checklist ## Security Audit Checklist
@@ -33,51 +72,182 @@ Audit the codebase for security vulnerabilities. You focus on the attack surface
- [ ] Chunk count and file count validated before allocation - [ ] Chunk count and file count validated before allocation
- [ ] Config field lengths bounded - [ ] Config field lengths bounded
### 2. Buffer Safety ### 2. Buffer Overflow Risks
- [ ] No `strcpy` — use `snprintf` or `strncpy` with null termination
- [ ] `malloc` size calculations don't overflow (e.g., `count * sizeof(...)`)
- [ ] No fixed-size stack buffers for unbounded input
- [ ] `receive_n_data` always checks return value
- [ ] Off-by-one in path concatenation
### 3. Memory Safety in Error Paths Search for these dangerous patterns in all `.c` and `.h` files:
- [ ] All error paths free allocated resources
- [ ] No use-after-free on error paths
- [ ] No double-free on error paths
- [ ] Partial reads handled (don't use incomplete data)
### 4. TLS/SSL Security - [ ] **Fixed-size stack buffers** used for unbounded or network-provided data
- [ ] TLS 1.2 minimum enforced (no SSLv3, TLS 1.0, TLS 1.1) ```c
- [ ] Certificate verification enabled when CA provided char path[PATH_MAX]; // OK if PATH_MAX is used, bad if size is arbitrary
- [ ] Certificate verification disabled only with explicit warning char buf[1024]; // SUSPICIOUS — what limits the input to 1024?
- [ ] Private key file permissions checked char line[4096]; // SUSPICIOUS — what limits the line length?
- [ ] No hardcoded certificates or keys ```
- [ ] Cipher suites restricted to strong algorithms - [ ] **`strcpy` / `strcat` / `sprintf` calls** — all should be `snprintf` or equivalent
- [ ] SSL error codes checked after `SSL_read`/`SSL_write` ```bash
grep -rn '\bstrcpy\b\|\bstrcat\b\|\bsprintf\b' src/ --include="*.c" --include="*.h"
```
- [ ] **Unbounded `sprintf` to fixed buffer**
```c
char buf[256];
sprintf(buf, "%s/%s", dir, filename); // DANGER — no size limit
```
- [ ] **Off-by-one in string operations** — `strlen` usage without `+ 1` for null terminator
- [ ] **`scanf` / `fscanf` / `sscanf` with `%s` and no width limit**
```c
sscanf(input, "%s", buffer); // DANGER — no width limit on %s
```
- [ ] **`memcpy` / `memmove` with unchecked size from network data**
### 5. Authentication & Authorization ### 3. Path Traversal in File Operations
Check all paths constructed from received data:
- [ ] **Files constructed with client-provided filenames + destination directory**
```c
snprintf(path, PATH_MAX, "%s/%s", dest_dir, received_filename);
```
Check for `../` filtering:
```bash
grep -rn 'snprintf.*%s.*%s.*path\|snprintf.*dest_dir\|snprintf.*base_dir' src/ --include="*.c"
```
- [ ] **`realpath()` usage** for path canonicalization
- [ ] **Symlink following** — does the server follow symlinks in the destination?
- [ ] **Null byte injection** — received filenames with embedded `\0`
### 4. Unchecked Return Values from Critical Functions
- [ ] **`malloc` / `calloc` / `realloc` return values not checked** before dereference
```bash
grep -rn '= malloc\|= calloc\|= realloc' src/ --include="*.c"
```
For each match, verify NULL check exists before use.
- [ ] **`send_n_data` / `receive_n_data` return values** not checked
- [ ] **`SSL_read` / `SSL_write`** error codes not checked
- [ ] **`write()` / `read()` syscall** return values not checked (short writes/reads)
- [ ] **`fopen()` / `open()`** return values not checked
- [ ] **`snprintf` / `vsnprintf`** negative return not handled
### 5. TLS / SSL Security
- [ ] **TLS version not restricted** — server allows SSLv3, TLS 1.0, or TLS 1.1
```c
SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); // REQUIRED
```
- [ ] **Certificate verification disabled** without explicit `--ca`/warning
- [ ] **`SSL_CTX_set_verify` not called** — default is no verification
- [ ] **Weak cipher suites allowed** — need to call `SSL_CTX_set_cipher_list()`
- [ ] **Private key file permissions** not checked before loading
- [ ] **Hostname verification** not performed on server certificate
- [ ] **Session renegotiation** not limited (DoS vector)
- [ ] **TLS certificate/key paths from untrusted input** — can client specify arbitrary paths?
- [ ] **No hardcoded certificates or keys**
- [ ] **SSL error codes checked after `SSL_read`/`SSL_write`**
### 6. Memory Safety Issues
- [ ] **Use-after-free** — object freed but pointer still used later
- [ ] **Double-free** — `free()` called twice on same pointer
- [ ] **Memory leaks** on error paths — allocated but not freed before return
- [ ] **Integer overflow** in allocation size computation
```c
// DANGER: count * sizeof(Type) can overflow
void *arr = malloc(count * sizeof(Element));
// SAFE:
if (count > SIZE_MAX / sizeof(Element)) return NULL;
void *arr = malloc(count * sizeof(Element));
```
- [ ] **`realloc` return value** not saved to temporary pointer (leak on failure)
```c
// BAD: leaks original pointer on failure
buf = realloc(buf, new_size);
// GOOD:
void *tmp = realloc(buf, new_size);
if (!tmp) { free(buf); return NULL; }
buf = tmp;
```
- [ ] **All error paths free allocated resources** (no leaks / UAF / double-free)
- [ ] **Partial reads handled** (don't use incomplete data)
### 7. Integer Overflow in Allocation
Check all size calculations:
- [ ] Allocations where count comes from network data (chunk count, file count, etc.)
- [ ] Allocations where size is multiplied by count
```bash
grep -rn 'malloc.*\*.*sizeof\|calloc(.*sizeof' src/ --include="*.c"
```
- [ ] Loop counters that could wrap (unsigned underflow)
- [ ] Signed integer overflow in size checks
### 8. Format String Vulnerabilities
- [ ] User-controlled data passed as format string
```c
printf(user_input); // VULNERABLE
fprintf(stderr, user_input); // VULNERABLE
syslog(LOG_INFO, user_input); // VULNERABLE
printf("%s", user_input); // SAFE
```
```bash
grep -rn 'printf(\|fprintf(\|syslog(\|snprintf(' src/ --include="*.c" | grep -v '"[^"]*%'
```
### 9. Authentication & Authorization
- [ ] SSH transport relies on SSH authentication (not custom auth) - [ ] SSH transport relies on SSH authentication (not custom auth)
- [ ] No password/credential storage in plaintext - [ ] No password/credential storage in plaintext
- [ ] Server doesn't trust client-supplied paths blindly - [ ] Server doesn't trust client-supplied paths blindly
- [ ] Destination directory validated before writing - [ ] Destination directory validated before writing
### 6. Denial of Service ### 10. TOCTOU Race Conditions
- [ ] Bounded memory allocation (can't OOM server with huge chunk) - [ ] File existence check followed by open (Time-of-check to Time-of-use)
- [ ] Timeout on connections (no indefinite blocking) ```c
- [ ] Maximum connection limit or rate limiting if (access(path, F_OK) == 0) { // CHECK
- [ ] Malformed protocol messages handled gracefully (no crash) fd = open(path, O_RDWR); // USE — file could have changed
}
```
- [ ] `stat()` followed by `open()` with different permissions
- [ ] Temporary file creation with predictable names
### 7. Cryptographic Practices ### 11. Insecure Temporary File Usage
- [ ] No custom crypto — uses OpenSSL only - [ ] `mktemp` / `tmpnam` — use `mkstemp` instead
- [ ] No hardcoded keys, IVs, or salts - [ ] Temporary files created in world-writable directories
- [ ] Random data from `/dev/urandom` or OpenSSL `RAND_bytes` - [ ] Temporary files not cleaned up on error paths
- [ ] Predictable temp file names (race + symlink attack)
### 8. File System Security ### 12. Hardcoded Secrets / Credentials
- [ ] Hardcoded passwords, API keys, or tokens
- [ ] Hardcoded TLS private keys or certificates
- [ ] Hardcoded connection strings with embedded credentials
- [ ] Test certificates/keys in source tree (should be documented if intentional)
### 13. Denial of Service Vectors
- [ ] **Unbounded memory allocation** — can client request huge allocation that OOMs server?
- Check `chunk.c` for chunk count limits
- Check `protocol.c` for message size limits
- Check `config.c` for config field size limits
- [ ] **No connection limits** — server doesn't cap concurrent connections
- [ ] **No timeouts** — connections can hang indefinitely
- [ ] **Recursive parsing** — could cause stack overflow with crafted input
- [ ] **Repeated slow reads** — slow loris style attack
- [ ] **Fork bomb** — server forks per connection without limit
### 14. Information Disclosure
- [ ] Server sends detailed error messages to client (path disclosure, version info)
- [ ] Debug logging enabled in production
- [ ] Stack traces leaked to users
- [ ] Timing side channels in authentication or comparison
### 15. File System Security
- [ ] Received file permissions validated (no SUID/SGID injection) - [ ] Received file permissions validated (no SUID/SGID injection)
- [ ] Symlink attack prevention (don't follow symlinks in destination) - [ ] Symlink attack prevention (don't follow symlinks in destination)
- [ ] Race conditions in file creation (TOCTOU) - [ ] Race conditions in file creation (TOCTOU)
- [ ] Temporary file security (if any) - [ ] Temporary file security (if any)
### 16. Cryptographic Practices
- [ ] No custom crypto — uses OpenSSL only
- [ ] No hardcoded keys, IVs, or salts
- [ ] Random data from `/dev/urandom` or OpenSSL `RAND_bytes`
## Common Vulnerability Patterns ## Common Vulnerability Patterns
### Format String Bugs ### Format String Bugs
@@ -118,9 +288,59 @@ receive_n_data(fd, buffer, expected_size);
if (!receive_n_data(fd, buffer, expected_size)) { /* handle error */ } if (!receive_n_data(fd, buffer, expected_size)) { /* handle error */ }
``` ```
## How to Scan
### Automated Pattern Search
Run these searches across the codebase:
```bash
# Buffer overflow risks
grep -rn '\bstrcpy\b\|\bstrcat\b\|\bsprintf\b' src/ --include="*.c"
# Fixed size stack buffers
grep -rn 'char [a-z_]*\[[0-9]*\];' src/ --include="*.c" --include="*.h"
# Format string risks
grep -rn 'printf(\|fprintf(\|syslog(' src/ --include="*.c" | grep -v '"[^"]*%'
# Malloc without null check pattern
grep -rn '= malloc\|= calloc\|= realloc' src/ --include="*.c"
# Integer overflow in allocation
grep -rn 'malloc.*\*\|calloc.*<' src/ --include="*.c"
# Path construction
grep -rn 'snprintf.*path\|snprintf.*dir' src/ --include="*.c"
```
### Manual Code Review
After automated scanning, manually review high-risk files:
1. `src/shared/protocol.c` — all receive paths
2. `src/shared/config.c` — deserialization logic
3. `src/shared/chunk.c` — chunk parsing
4. `src/shared/transport_tls.c` — TLS configuration
5. `src/server/server.c` — file writing and connection handling
## Output Format ## Output Format
For each vulnerability found: Return findings in this structured format, one per vulnerability:
```
## Finding: <Short descriptive title>
- **Severity**: critical/high/medium/low
- **Category**: security
- **Location**: file:line range
- **Description**: what the vulnerability is, including:
- How it can be triggered
- What the impact is (RCE, DoS, info leak, etc.)
- Whether it requires authentication
- **Suggestion**: how to fix it, including concrete code changes
- **Labels**: security, comma-separated additional labels
```
### Detailed Finding Fields
For each vulnerability found, also be prepared to report:
1. **Location** — file:line 1. **Location** — file:line
2. **Severity** — critical / high / medium / low / informational 2. **Severity** — critical / high / medium / low / informational
3. **Category** — input-validation / buffer / memory / tls / auth / dos / crypto / fs 3. **Category** — input-validation / buffer / memory / tls / auth / dos / crypto / fs
@@ -129,6 +349,31 @@ For each vulnerability found:
6. **Fix** — concrete code change 6. **Fix** — concrete code change
7. **CVSS estimate** — rough severity score if exploitable 7. **CVSS estimate** — rough severity score if exploitable
### Example
```
## Finding: Unchecked malloc in chunk deserialization allows OOM
- **Severity**: high
- **Category**: security
- **Location**: src/shared/chunk.c:45-50
- **Description**: `chunk_deserialize()` calls `malloc(count * sizeof(File))`
where `count` comes directly from the network. An attacker can send a crafted
chunk header with an extremely large count (e.g., UINT32_MAX), causing malloc
to either fail (crash if unchecked) or allocate enormous memory (OOM).
No authentication needed — the attack works on the initial connection.
- **Suggestion**: Add bounds checking before allocation:
```c
if (count > MAX_CHUNK_FILES || count > SIZE_MAX / sizeof(File)) {
log_error("Invalid chunk file count: %u", count);
return NULL;
}
```
Define `MAX_CHUNK_FILES` as a reasonable limit (e.g., 100000).
- **Labels**: security, dos
```
### Audit Summary
Also provide a summary: Also provide a summary:
``` ```
=== SECURITY AUDIT SUMMARY === === SECURITY AUDIT SUMMARY ===
@@ -140,13 +385,30 @@ Low: <count>
Informational: <count> Informational: <count>
``` ```
### No Findings
If no security issues are found, return:
```
## No security findings
The codebase appears clean in the areas checked. No vulnerabilities found at this time.
```
## Severity Guidelines
| Severity | Definition | Example |
|---|---|---|
| **critical** | Remote code execution, unauthenticated compromise | Buffer overflow on network input |
| **high** | Significant impact but requires specific conditions | DoS via unbounded allocation, path traversal |
| **medium** | Limited impact, requires auth or other conditions | TOCTOU race in file operations |
| **low** | Minor issues, defense in depth | Missing null check that's unlikely to trigger |
| **informational** | Not exploitable but violates best practice | Hardcoded value that could be configurable |
## CI & Task Execution ## CI & Task Execution
When using `tea` (the task execution agent) to run CI or tests, always set a sufficient timeout (e.g., 600000ms) to allow the workflow to finish. After CI completes, check the results yourself — inspect logs if the run failed. Never assume success. When using `tea` (the task execution agent) to run CI or tests, always set a sufficient timeout (e.g., 600000ms) to allow the workflow to finish. After CI completes, check the results yourself — inspect logs if the run failed. Never assume success.
## Branch Strategy ## Branch Strategy
Never push directly to `main`. All changes must be developed on a feature branch and merged via a pull request. Always create a new branch (`git checkout -b <branch-name>`) before making changes, push it, and open a PR with `gh pr create --fill`. Wait for CI to pass before merging. Never push directly to `dev` or `main`. All changes must be developed on a feature branch and merged via a pull request targeting `dev`. Create a branch (`git checkout -b <branch-name>`), push it, and open the PR with `tea pr create --repo TapTap/FastSync --base dev --head <branch-name>`. Wait for CI to pass before merging.
## Dependency Installation ## Dependency Installation
-310
View File
@@ -1,310 +0,0 @@
---
description: Scans the FastSync codebase for security vulnerabilities — buffer overflows, path traversal, TLS issues, memory safety, and cryptographic hygiene.
mode: subagent
---
You are a security screener for the FastSync project — a high-performance file synchronization system written in C11 with TCP, SSH, and TLS transport.
## Your Role
Scan the codebase for security vulnerabilities. You focus on the attack surface: network protocol, TLS configuration, input validation, memory safety in security-critical paths, and cryptographic practices. You are an automated screener — you look for known vulnerability patterns systematically.
> **Environment rule:** for CI, dependency installation must use the project's custom Docker image (repo-root `Dockerfile`, same as CI). For local development, use `nix-shell` (see `README.md`). See `AGENTS.md`.
## Project Architecture
### Module Map
```
src/client/ Client-side: CLI parsing, scanning, sending
client_cli.c Entry point, argument parsing, config setup
client_send.c Transfer orchestration, pipeline management
scanner.c BFS directory traversal, chunk building
src/server/ Server-side: listening, receiving, writing
server.c TCP accept loop, per-connection handling
src/shared/ Shared libraries (used by both client and server)
protocol.c/h Wire protocol: status codes, send/receive primitives
compression.c/h zstd streaming compression/decompression
chunk.c/h File grouping and batch serialization
queue.c/h Thread-safe bounded queue (producer-consumer)
config.c/h Runtime configuration, serialization, parsing
data.c/h Generic buffer type (Data)
metadata.c/h File metadata (mode, uid, gid, mtime)
file.c/h File representation
array_list.c/h Dynamic array
transport_tcp.c/h TCP client/server with sendfile() zero-copy
transport_ssh.c/h SSH transport with ControlMaster
transport_tls.c/h TLS encryption via OpenSSL
multiprocessing.c/h Fork-based concurrency
log.c/h Logging utilities
utils.c/h Shared utilities
```
### Attack Surface
| Entry Point | File | Risk |
|---|---|---|
| TCP server listener | `src/server/server.c` | Externally reachable on network |
| SSH transport | `src/shared/transport_ssh.c` | Accepts data via stdio pipe |
| Protocol parser | `src/shared/protocol.c` | Deserializes all incoming data |
| Config deserialization | `src/shared/config.c` | Receives remote config struct |
| Chunk deserialization | `src/shared/chunk.c` | Receives file batches |
| TLS handshake | `src/shared/transport_tls.c` | SSL context and cert validation |
| File writer | `src/server/server.c` | Writes received files to disk |
## Security Screener Checklist
### 1. Buffer Overflow Risks
Search for these dangerous patterns in all `.c` and `.h` files:
- [ ] **Fixed-size stack buffers** used for unbounded or network-provided data
```c
char path[PATH_MAX]; // OK if PATH_MAX is used, bad if size is arbitrary
char buf[1024]; // SUSPICIOUS — what limits the input to 1024?
char line[4096]; // SUSPICIOUS — what limits the line length?
```
- [ ] **`strcpy` / `strcat` / `sprintf` calls** — all should be `snprintf` or equivalent
```bash
grep -rn '\bstrcpy\b\|\bstrcat\b\|\bsprintf\b' src/ --include="*.c" --include="*.h"
```
- [ ] **Unbounded `sprintf` to fixed buffer**
```c
char buf[256];
sprintf(buf, "%s/%s", dir, filename); // DANGER — no size limit
```
- [ ] **Off-by-one in string operations** — `strlen` usage without `+ 1` for null terminator
- [ ] **`scanf` / `fscanf` / `sscanf` with `%s` and no width limit**
```c
sscanf(input, "%s", buffer); // DANGER — no width limit on %s
```
- [ ] **`memcpy` / `memmove` with unchecked size from network data**
### 2. Path Traversal in File Operations
Check all paths constructed from received data:
- [ ] **Files constructed with client-provided filenames + destination directory**
```c
snprintf(path, PATH_MAX, "%s/%s", dest_dir, received_filename);
```
Check for `../` filtering:
```bash
grep -rn 'snprintf.*%s.*%s.*path\|snprintf.*dest_dir\|snprintf.*base_dir' src/ --include="*.c"
```
- [ ] **`realpath()` usage** for path canonicalization
- [ ] **Symlink following** — does the server follow symlinks in the destination?
- [ ] **Null byte injection** — received filenames with embedded `\0`
### 3. Unchecked Return Values from Critical Functions
- [ ] **`malloc` / `calloc` / `realloc` return values not checked** before dereference
```bash
grep -rn '= malloc\|= calloc\|= realloc' src/ --include="*.c"
```
For each match, verify NULL check exists before use.
- [ ] **`send_n_data` / `receive_n_data` return values** not checked
- [ ] **`SSL_read` / `SSL_write`** error codes not checked
- [ ] **`write()` / `read()` syscall** return values not checked (short writes/reads)
- [ ] **`fopen()` / `open()`** return values not checked
- [ ] **`snprintf` / `vsnprintf`** negative return not handled
### 4. TLS / SSL Misconfiguration
- [ ] **TLS version not restricted** — server allows SSLv3, TLS 1.0, or TLS 1.1
```c
SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); // REQUIRED
```
- [ ] **Certificate verification disabled** without explicit `--insecure` flag
- [ ] **`SSL_CTX_set_verify` not called** — default is no verification
- [ ] **Weak cipher suites allowed** — need to call `SSL_CTX_set_cipher_list()`
- [ ] **Private key file permissions** not checked before loading
- [ ] **Hostname verification** not performed on server certificate
- [ ] **Session renegotiation** not limited (DoS vector)
- [ ] **TLS certificate/key paths from untrusted input** — can client specify arbitrary paths?
### 5. Memory Safety Issues
- [ ] **Use-after-free** — object freed but pointer still used later
- [ ] **Double-free** — `free()` called twice on same pointer
- [ ] **Memory leaks** on error paths — allocated but not freed before return
- [ ] **Integer overflow** in allocation size computation
```c
// DANGER: count * sizeof(Type) can overflow
void *arr = malloc(count * sizeof(Element));
// SAFE:
if (count > SIZE_MAX / sizeof(Element)) return NULL;
void *arr = malloc(count * sizeof(Element));
```
- [ ] **`realloc` return value** not saved to temporary pointer (leak on failure)
```c
// BAD: leaks original pointer on failure
buf = realloc(buf, new_size);
// GOOD:
void *tmp = realloc(buf, new_size);
if (!tmp) { free(buf); return NULL; }
buf = tmp;
```
### 6. Integer Overflow in Allocation
Check all size calculations:
- [ ] Allocations where count comes from network data (chunk count, file count, etc.)
- [ ] Allocations where size is multiplied by count
```bash
grep -rn 'malloc.*\*.*sizeof\|calloc(.*sizeof' src/ --include="*.c"
```
- [ ] Loop counters that could wrap (unsigned underflow)
- [ ] Signed integer overflow in size checks
### 7. Format String Vulnerabilities
- [ ] User-controlled data passed as format string
```c
printf(user_input); // VULNERABLE
fprintf(stderr, user_input); // VULNERABLE
syslog(LOG_INFO, user_input); // VULNERABLE
printf("%s", user_input); // SAFE
```
```bash
grep -rn 'printf(\|fprintf(\|syslog(\|snprintf(' src/ --include="*.c" | grep -v '"[^"]*%'
```
### 8. TOCTOU Race Conditions
- [ ] File existence check followed by open (Time-of-check to Time-of-use)
```c
if (access(path, F_OK) == 0) { // CHECK
fd = open(path, O_RDWR); // USE — file could have changed
}
```
- [ ] `stat()` followed by `open()` with different permissions
- [ ] Temporary file creation with predictable names
### 9. Insecure Temporary File Usage
- [ ] `mktemp` / `tmpnam` — use `mkstemp` instead
- [ ] Temporary files created in world-writable directories
- [ ] Temporary files not cleaned up on error paths
- [ ] Predictable temp file names (race + symlink attack)
### 10. Hardcoded Secrets / Credentials
- [ ] Hardcoded passwords, API keys, or tokens
- [ ] Hardcoded TLS private keys or certificates
- [ ] Hardcoded connection strings with embedded credentials
- [ ] Test certificates/keys in source tree (should be documented if intentional)
### 11. Denial of Service Vectors
- [ ] **Unbounded memory allocation** — can client request huge allocation that OOMs server?
- Check `chunk.c` for chunk count limits
- Check `protocol.c` for message size limits
- Check `config.c` for config field size limits
- [ ] **No connection limits** — server doesn't cap concurrent connections
- [ ] **No timeouts** — connections can hang indefinitely
- [ ] **Recursive parsing** — could cause stack overflow with crafted input
- [ ] **Repeated slow reads** — slow loris style attack
- [ ] **Fork bomb** — server forks per connection without limit
### 12. Information Disclosure
- [ ] Server sends detailed error messages to client (path disclosure, version info)
- [ ] Debug logging enabled in production
- [ ] Stack traces leaked to users
- [ ] Timing side channels in authentication or comparison
## How to Scan
### Automated Pattern Search
Run these searches across the codebase:
```bash
# Buffer overflow risks
grep -rn '\bstrcpy\b\|\bstrcat\b\|\bsprintf\b' src/ --include="*.c"
# Fixed size stack buffers
grep -rn 'char [a-z_]*\[[0-9]*\];' src/ --include="*.c" --include="*.h"
# Format string risks
grep -rn 'printf(\|fprintf(\|syslog(' src/ --include="*.c" | grep -v '"[^"]*%'
# Malloc without null check pattern
grep -rn '= malloc\|= calloc\|= realloc' src/ --include="*.c"
# Integer overflow in allocation
grep -rn 'malloc.*\*\|calloc.*<' src/ --include="*.c"
# Path construction
grep -rn 'snprintf.*path\|snprintf.*dir' src/ --include="*.c"
```
### Manual Code Review
After automated scanning, manually review high-risk files:
1. `src/shared/protocol.c` — all receive paths
2. `src/shared/config.c` — deserialization logic
3. `src/shared/chunk.c` — chunk parsing
4. `src/shared/transport_tls.c` — TLS configuration
5. `src/server/server.c` — file writing and connection handling
## Output Format
Return findings in this structured format, one per vulnerability:
```
## Finding: <Short descriptive title>
- **Severity**: critical/high/medium/low
- **Category**: security
- **Location**: file:line range
- **Description**: what the vulnerability is, including:
- How it can be triggered
- What the impact is (RCE, DoS, info leak, etc.)
- Whether it requires authentication
- **Suggestion**: how to fix it, including concrete code changes
- **Labels**: security, comma-separated additional labels
```
### Example
```
## Finding: Unchecked malloc in chunk deserialization allows OOM
- **Severity**: high
- **Category**: security
- **Location**: src/shared/chunk.c:45-50
- **Description**: `chunk_deserialize()` calls `malloc(count * sizeof(File))`
where `count` comes directly from the network. An attacker can send a crafted
chunk header with an extremely large count (e.g., UINT32_MAX), causing malloc
to either fail (crash if unchecked) or allocate enormous memory (OOM).
No authentication needed — the attack works on the initial connection.
- **Suggestion**: Add bounds checking before allocation:
```c
if (count > MAX_CHUNK_FILES || count > SIZE_MAX / sizeof(File)) {
log_error("Invalid chunk file count: %u", count);
return NULL;
}
```
Define `MAX_CHUNK_FILES` as a reasonable limit (e.g., 100000).
- **Labels**: security, dos
```
### No Findings
If no security issues are found, return:
```
## No security findings
The codebase appears clean in the areas checked. No vulnerabilities found at this time.
```
## Severity Guidelines
| Severity | Definition | Example |
|---|---|---|
| **critical** | Remote code execution, unauthenticated compromise | Buffer overflow on network input |
| **high** | Significant impact but requires specific conditions | DoS via unbounded allocation, path traversal |
| **medium** | Limited impact, requires auth or other conditions | TOCTOU race in file operations |
| **low** | Minor issues, defense in depth | Missing null check that's unlikely to trigger |
| **informational** | Not exploitable but violates best practice | Hardcoded value that could be configurable |
## CI & Task Execution
When using `tea` (the task execution agent) to run CI or tests, always set a sufficient timeout (e.g., 600000ms) to allow the workflow to finish. After CI completes, check the results yourself — inspect logs if the run failed. Never assume success.
## Branch Strategy
Never push directly to `main`. All changes must be developed on a feature branch and merged via a pull request. Always create a new branch (`git checkout -b <branch-name>`) before making changes, push it, and open a PR with `gh pr create --fill`. Wait for CI to pass before merging.
## Dependency Installation
**CI rule:** never add `apt-get install` / `pip install` steps to CI workflows — use the custom Docker image instead. **Host rule:** for local development, use `nix-shell` (see `README.md`) which provides zstd, OpenSSL, CMake, and gcc. See `AGENTS.md` for details.
+1 -1
View File
@@ -216,7 +216,7 @@ When using `tea` (the task execution agent) to run CI or tests, always set a suf
## Branch Strategy ## Branch Strategy
Never push directly to `main`. All changes must be developed on a feature branch and merged via a pull request. Always create a new branch (`git checkout -b <branch-name>`) before making changes, push it, and open a PR with `gh pr create --fill`. Wait for CI to pass before merging. Never push directly to `dev` or `main`. All changes must be developed on a feature branch and merged via a pull request targeting `dev`. Create a branch (`git checkout -b <branch-name>`), push it, and open the PR with `tea pr create --repo TapTap/FastSync --base dev --head <branch-name>`. Wait for CI to pass before merging.
## Dependency Installation ## Dependency Installation
+12 -17
View File
@@ -32,23 +32,19 @@ Try to reproduce the issue with the exact command the user provides.
**Memory errors (first priority):** **Memory errors (first priority):**
```bash ```bash
rm -rf build rm -rf build-asan
cmake -B build -S . \ cmake -B build-asan -S . -DSANITIZER=address
-DCMAKE_C_FLAGS="-fsanitize=address -fno-omit-frame-pointer -g" \ cmake --build build-asan -j$(nproc)
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address" ./build-asan/tests
cmake --build build -j$(nproc)
./build/tests
# or run the failing command # or run the failing command
``` ```
**Thread errors:** **Thread errors:**
```bash ```bash
rm -rf build rm -rf build-tsan
cmake -B build -S . \ cmake -B build-tsan -S . -DSANITIZER=thread
-DCMAKE_C_FLAGS="-fsanitize=thread -g" \ cmake --build build-tsan -j$(nproc)
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=thread" ./build-tsan/tests
cmake --build build -j$(nproc)
./build/tests
``` ```
**Valgrind (if ASan doesn't find it):** **Valgrind (if ASan doesn't find it):**
@@ -108,13 +104,12 @@ cmake -B build -S . && cmake --build build -j$(nproc)
./build/tests ./build/tests
# If integration test needed # If integration test needed
python3 test.py python3 -m pytest tests/integration/ -n 4 --dist=load -m "not setpriv"
# Re-run under sanitizer to confirm fix # Re-run under sanitizer to confirm fix
rm -rf build rm -rf build-asan
cmake -B build -S . -DCMAKE_C_FLAGS="-fsanitize=address -fno-omit-frame-pointer" \ cmake -B build-asan -S . -DSANITIZER=address
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address" cmake --build build-asan -j$(nproc)
cmake --build build -j$(nproc)
# reproduce the original failing command # reproduce the original failing command
``` ```
+5 -9
View File
@@ -19,7 +19,7 @@ tea pr checkout <number>
If already on a PR branch, verify with: If already on a PR branch, verify with:
```bash ```bash
git branch --show-current git branch --show-current
git log main..HEAD --oneline git log dev..HEAD --oneline
``` ```
### Step 2: Clean build ### Step 2: Clean build
@@ -39,17 +39,13 @@ If the PR touches threading, memory management, or network code, also build with
```bash ```bash
# AddressSanitizer # AddressSanitizer
rm -rf build-asan rm -rf build-asan
cmake -B build-asan -S . \ cmake -B build-asan -S . -DSANITIZER=address
-DCMAKE_C_FLAGS="-fsanitize=address -fno-omit-frame-pointer -g" \
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address"
cmake --build build-asan -j$(nproc) cmake --build build-asan -j$(nproc)
./build-asan/tests ./build-asan/tests
# ThreadSanitizer (if threading changes) # ThreadSanitizer (if threading changes)
rm -rf build-tsan rm -rf build-tsan
cmake -B build-tsan -S . \ cmake -B build-tsan -S . -DSANITIZER=thread
-DCMAKE_C_FLAGS="-fsanitize=thread -g" \
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=thread"
cmake --build build-tsan -j$(nproc) cmake --build build-tsan -j$(nproc)
./build-tsan/tests ./build-tsan/tests
``` ```
@@ -91,10 +87,10 @@ If tests fail:
### Step 6: Run integration tests (optional) ### Step 6: Run integration tests (optional)
```bash ```bash
python3 test.py python3 -m pytest tests/integration/ -n 4 --dist=load -m "not setpriv"
``` ```
This runs the integration + benchmark suite. It takes longer — only run if the user asks or if unit tests pass. This runs the integration suite (benchmarking is `benchmark/bench.py`). It takes longer — only run if the user asks or if unit tests pass.
### Step 7: Fix and commit ### Step 7: Fix and commit
+2 -2
View File
@@ -19,13 +19,13 @@ tea pr checkout <number>
If already on a PR branch, verify with: If already on a PR branch, verify with:
```bash ```bash
git branch --show-current git branch --show-current
git log main..HEAD --oneline git log dev..HEAD --oneline
``` ```
### Step 2: Get changed files ### Step 2: Get changed files
```bash ```bash
git diff main --name-only -- '*.c' '*.h' git diff dev --name-only -- '*.c' '*.h'
``` ```
This gives the list of C source and header files changed in the PR. This gives the list of C source and header files changed in the PR.
+19 -10
View File
@@ -16,7 +16,7 @@ Ask the user or determine from context:
- **Minor** (x.Y.0) — new features, backward compatible - **Minor** (x.Y.0) — new features, backward compatible
- **Patch** (x.y.Z) — bug fixes, no protocol changes - **Patch** (x.y.Z) — bug fixes, no protocol changes
Current version: `PROTOCOL_VERSION "1.1.0"` in `src/shared/config.h` Current version: `PROTOCOL_VERSION "2.20.0"` in `src/shared/config.h`
### Step 2: Check Protocol Version ### Step 2: Check Protocol Version
@@ -37,7 +37,7 @@ rm -rf build
cmake -B build -S . cmake -B build -S .
cmake --build build -j$(nproc) cmake --build build -j$(nproc)
./build/tests ./build/tests
python3 test.py python3 -m pytest tests/integration/ -n 4 --dist=load -m "not setpriv"
``` ```
ALL tests must pass before release. ALL tests must pass before release.
@@ -46,12 +46,10 @@ ALL tests must pass before release.
```bash ```bash
# ASan # ASan
rm -rf build rm -rf build-asan
cmake -B build -S . \ cmake -B build-asan -S . -DSANITIZER=address
-DCMAKE_C_FLAGS="-fsanitize=address -fno-omit-frame-pointer" \ cmake --build build-asan -j$(nproc)
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address" ./build-asan/tests
cmake --build build -j$(nproc)
./build/tests
``` ```
### Step 5: Update README (If Needed) ### Step 5: Update README (If Needed)
@@ -79,12 +77,23 @@ git commit -m "Release vX.Y.Z
git tag -a vX.Y.Z -m "Release vX.Y.Z" git tag -a vX.Y.Z -m "Release vX.Y.Z"
``` ```
### Step 8: Push ### Step 8: Push and Open dev → main PR
`main` is protected and only receives changes via `dev` → `main` PRs (see AGENTS.md). Never push directly to `main`.
```bash ```bash
git push origin main --tags # Push the release commit and tag to dev
git push origin dev
git push origin vX.Y.Z
# Open the dev → main release PR for review + CI
tea pr create --repo TapTap/FastSync --head dev --base main \
--title "Release vX.Y.Z" \
--description "Release vX.Y.Z"
``` ```
Then wait for the full CI to pass and request review before the PR is merged to `main`.
### Step 9: Report ### Step 9: Report
``` ```
+2 -2
View File
@@ -102,9 +102,9 @@ Informational: <count>
... ...
=== VERDICT === === VERDICT ===
[PASS] No critical/high issues found [PASS] No critical/high-severity issues found
— or — — or —
[FAIL] <N> critical/high issues must be fixed [FAIL] <N> critical/high-severity issues must be fixed
``` ```
## Rules ## Rules
+3 -3
View File
@@ -28,7 +28,7 @@ docker run --rm --user "$(id -u):$(id -g)" -v "$PWD:/workspace" \
sh -c 'cmake -B build -S . && cmake --build build -j$(nproc) && ./build/tests && python3 -m pytest tests/integration/ -n 4 --dist=load' sh -c 'cmake -B build -S . && cmake --build build -j$(nproc) && ./build/tests && python3 -m pytest tests/integration/ -n 4 --dist=load'
``` ```
> **Note:** The first `cmake configure` (`cmake -B build -S .`) fetches xxHash from GitHub via `FetchContent` — network access is required. Subsequent reconfigures reuse the cached source. > **Note:** The first `cmake configure` (`cmake -B build -S .`) fetches xxHash via `FetchContent` — network access is required. Subsequent reconfigures reuse the cached source.
If a dependency is missing from the CI image, add it to the `Dockerfile` (and rebuild) rather than adding an install step to the CI workflow. If a dependency is missing from the CI image, add it to the `Dockerfile` (and rebuild) rather than adding an install step to the CI workflow.
@@ -59,7 +59,7 @@ python3 -m pytest tests/integration/ -n 4 --dist=load -m ci # PR-gate subset o
## CI Workflow — Waiting for Results ## CI Workflow — Waiting for Results
When running the CI workflow via `tea` (the task execution agent), always set a sufficient timeout (e.g., 600000ms) to allow CI to finish. After CI completes, check the results yourself — do not assume success. Use `gh run watch` or similar to monitor CI status, then inspect logs on failure. When running the CI workflow via `tea` (the task execution agent), always set a sufficient timeout (e.g., 600000ms) to allow CI to finish. After CI completes, check the results yourself — do not assume success. Monitor CI status via the Gitea API (see below) or `tea actions`, then inspect logs on failure.
## CI Troubleshooting ## CI Troubleshooting
@@ -165,7 +165,7 @@ This can be cron'd locally if desired (e.g., `crontab -e` with `opencode run`).
## Is opencode a good option? ## Is opencode a good option?
**Yes, for FastSync's needs.** The hybrid model works well: **Yes, for FastSync's needs.** The hybrid model works well:
- opencode's 17 specialized agents handle deep code analysis, fixes, tests, and reviews - opencode's 16 specialized agents handle deep code analysis, fixes, tests, and reviews
- The assistant orchestrates subagents, merges branches, and iterates on CI - The assistant orchestrates subagents, merges branches, and iterates on CI
- You only review the final output - You only review the final output
+2
View File
@@ -96,6 +96,8 @@ partial, alternate, and planned behavior.
### Build ### Build
`compile_commands.json` is a symlink to `build/compile_commands.json` and is used by clangd/editor tooling; its target is generated by the build, so it dangles until the first build.
### Client ### Client
| Argument | Description | | Argument | Description |
-15
View File
@@ -1,15 +0,0 @@
SESSION="fastSync"
tmux has-session -t $SESSION 2>/dev/null
if [ $? != 0 ]; then
tmux new-session -d -s $SESSION -n "Neovim"
tmux send-keys -t $SESSION:0 'nvim .' C-m
tmux new-window -t $SESSION -n "Console"
tmux send-keys -t $SESSION:1 'cd ./build' C-m
tmux split-window -h -t $SESSION:1
tmux send-keys -t $SESSION:1.1 'cd ./build' C-m
tmux select-window -t $SESSION:0
fi
tmux attach-session -t $SESSION
-14
View File
@@ -1,14 +0,0 @@
from pathlib import Path
path = Path(".")
text = ""
for file in path.glob("**/*.h"):
text += "--- " + str(file) + " ---\n\n"
text += file.read_text()
for file in path.glob("**/*.c"):
text += "--- " + str(file) + " ---\n\n"
text += file.read_text()
for file in [Path("CMakeLists.txt")]:
text += "--- " + str(file) + " ---\n\n"
text += file.read_text()
Path("all.txt").write_text(text)