From e5e0d30c234dc7f9dc8ef63607943f7cba6e3e19 Mon Sep 17 00:00:00 2001 From: Michel Machado Date: Mon, 21 Sep 2026 11:20:18 -0400 Subject: [PATCH 1/5] zed: Convert VS Code configuration to Zed Translate `.vscode` configurations with corresponding `.zed` files: - Add `.zed/tasks.json` defining build tasks (`Build all` and `make clean`) with automatic saving of modified buffers before builds. - Add `.zed/debug.json` with launch profiles for f3brew, f3probe, f3write, and f3read using the GDB adapter, including inline build steps to ensure directory "a" exists. - Copy `gdb-sudo.sh` to `.zed/gdb-sudo.sh` for elevated debugging. --- .zed/debug.json | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ .zed/gdb-sudo.sh | 3 +++ .zed/tasks.json | 13 +++++++++ 3 files changed, 84 insertions(+) create mode 100644 .zed/debug.json create mode 100755 .zed/gdb-sudo.sh create mode 100644 .zed/tasks.json diff --git a/.zed/debug.json b/.zed/debug.json new file mode 100644 index 0000000..02e4412 --- /dev/null +++ b/.zed/debug.json @@ -0,0 +1,68 @@ +[ + // Use adapter "CodeLLDB" because "GDB" is not working on gdb versions + // before gdb 17. + // See https://github.com/zed-industries/zed/issues/41753 for more details. + { + "label": "f3brew test", + "adapter": "CodeLLDB", + "request": "launch", + "program": "$ZED_WORKTREE_ROOT/build/f3brew", + "args": ["--debug", "--fix-cmd", "test"] + }, + { + "label": "f3probe unit-test", + "adapter": "CodeLLDB", + "request": "launch", + "program": "$ZED_WORKTREE_ROOT/build/f3probe", + "args": ["--debug-unit-test", "test"] + }, + { + "label": "f3probe simple test", + "adapter": "CodeLLDB", + "request": "launch", + "program": "$ZED_WORKTREE_ROOT/build/f3probe", + "args": ["--debug", "--destructive", "--verbose", "test"] + }, + { + "label": "f3probe test", + "adapter": "CodeLLDB", + "request": "launch", + "program": "$ZED_WORKTREE_ROOT/build/f3probe", + "args": [ + "--debug-real-size=1G", + "--debug-fake-size=1T", + "--debug-wrap=40", + "--debug-cache-order=21", + "--debug-strict-cache", + "--destructive", + "--verbose", + "test" + ] + // Uncomment the following line to run under sudo: + // "gdb_path": "$ZED_WORKTREE_ROOT/.zed/gdb-sudo.sh" + }, + { + "label": "f3write a", + "adapter": "CodeLLDB", + "request": "launch", + "build": { + "command": "mkdir", + // -p creates the directory if needed and avoids failing if it already exists. + "args": ["-p", "a"] + }, + "program": "$ZED_WORKTREE_ROOT/build/f3write", + "args": ["--end-at=5", "a"] + }, + { + "label": "f3read a", + "adapter": "CodeLLDB", + "request": "launch", + "build": { + "command": "mkdir", + // -p creates the directory if needed and avoids failing if it already exists. + "args": ["-p", "a"] + }, + "program": "$ZED_WORKTREE_ROOT/build/f3read", + "args": ["a"] + } +] diff --git a/.zed/gdb-sudo.sh b/.zed/gdb-sudo.sh new file mode 100755 index 0000000..6a7e5f5 --- /dev/null +++ b/.zed/gdb-sudo.sh @@ -0,0 +1,3 @@ +#!/bin/bash +#sudo /usr/bin/gdb "$@" +pkexec /usr/bin/gdb "$@" diff --git a/.zed/tasks.json b/.zed/tasks.json new file mode 100644 index 0000000..b1099c4 --- /dev/null +++ b/.zed/tasks.json @@ -0,0 +1,13 @@ +[ + { + "label": "F3: Build", + "command": "make", + "args": ["all", "extra"], + "save": "all" + }, + { + "label": "F3: Clean", + "command": "make", + "args": ["clean"] + } +] From 5c66fa79554d70f60fd39559ab5bde4147e6e7e0 Mon Sep 17 00:00:00 2001 From: Michel Machado Date: Mon, 21 Sep 2026 20:03:53 -0400 Subject: [PATCH 2/5] agents: convert coding style rule to skill Migrate the F3 coding style from the Antigravity IDE v1.0 rule format in .agents/rules/coding-style.md to an agent skill located in .agents/skills/coding-style/SKILL.md. --- .../coding-style/SKILL.md} | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) rename .agents/{rules/coding-style.md => skills/coding-style/SKILL.md} (78%) diff --git a/.agents/rules/coding-style.md b/.agents/skills/coding-style/SKILL.md similarity index 78% rename from .agents/rules/coding-style.md rename to .agents/skills/coding-style/SKILL.md index 28d6a98..c719b8c 100644 --- a/.agents/rules/coding-style.md +++ b/.agents/skills/coding-style/SKILL.md @@ -1,10 +1,12 @@ --- -trigger: model_decision -description: After generating or editing code +name: coding-style +description: Coding style and formatting rules for F3. Use when writing, modifying, refactoring, or reviewing C code in the F3 project. --- # F3 Coding Style +When generating, modifying, or reviewing C code in the F3 project, follow these coding style guidelines and conventions. + ## 1. General Principles - **Language**: C (C17 standard as specified in the Makefile). - **Line Length**: Maximum 80 columns. The only exception is for literal strings to facilitate grep-ability of output messages. @@ -14,10 +16,10 @@ description: After generating or editing code - **Indentation**: Uses **Tabs** for indentation. - **Braces**: K&R style. Opening braces `{` are on the same line as the statement (`if`, `while`, `for`, `switch`, `struct`, and function definitions). - **Whitespace**: - - Space after keywords (`if`, `while`, `for`, `switch`, `do`). - - No space between function name and the opening parenthesis `(`. - - Pointers: `char *ptr` (space before the asterisk, not after). - - Alignment: Struct member assignments and function parameters are often aligned using tabs when spanning multiple lines. + - Space after keywords (`if`, `while`, `for`, `switch`, `do`). + - No space between function name and the opening parenthesis `(`. + - Pointers: `char *ptr` (space before the asterisk, not after). + - Alignment: Struct member assignments and function parameters are often aligned using tabs when spanning multiple lines. ## 3. Naming Conventions - **Files**: Lowercase with `snake_case` (e.g., `f3read.c`, `libutils.h`). @@ -48,4 +50,4 @@ description: After generating or editing code ## 8. Comments - **Style**: Uses C-style comments `/* ... */`. -- **Placement**: Comments are placed above the code they describe or as trailing comments aligned with tabs. \ No newline at end of file +- **Placement**: Comments are placed above the code they describe or as trailing comments aligned with tabs. From fc3d431b6c27a8d72c8553213219d0b6630814e9 Mon Sep 17 00:00:00 2001 From: Michel Machado Date: Mon, 21 Sep 2026 20:12:03 -0400 Subject: [PATCH 3/5] agents: add commit-message skill Define conventions and guidelines for generating Git commit messages in F3 based on repository history and standards established across AltraMayor projects. This skill provides agents with rules for subsystem prefixes, subject line formatting, referencing functions with (), noting manual sections for system calls and library functions, and formatting issue closures. --- .agents/skills/commit-message/SKILL.md | 148 +++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 .agents/skills/commit-message/SKILL.md diff --git a/.agents/skills/commit-message/SKILL.md b/.agents/skills/commit-message/SKILL.md new file mode 100644 index 0000000..70e4541 --- /dev/null +++ b/.agents/skills/commit-message/SKILL.md @@ -0,0 +1,148 @@ +--- +name: commit-message +description: Rules and guidelines for generating Git commit messages in F3. Use when writing, formatting, or reviewing Git commit messages for this repository. +--- + +All commit messages in F3 must follow the project's established conventions. + +```text +: + + + + +``` + +1. **Subsystem Prefix (``)**: + - Matches the affected tool, library, directory, or configuration in lowercase. + - **Applications / Binaries**: + Use the binary name (e.g. `f3write`, `f3read`, `f3probe`, `f3brew`, `f3fix`). + When a change touches multiple related tools, join them with a slash (e.g. `f3write/f3read`, `f3write/f3read/f3brew`, `f3brew/f3probe`). + - **Libraries**: + Use the library name (e.g. `libflow`, `libprobe`, `libutils`, `libdevs`, `libfile`). + - **Build and CI**: + Use `Makefile`, `GitHub Actions` (or `GitHub`). + - **Documentation and Metadata**: + Use `README`, `doc`, `man` (or specific manual page, e.g. `f3read.1`), `changelog`, `.gitignore`. + - **Developer Tools and Workspace Configuration**: + Use `agents`, `scripts`, `zed`. + - **Project-Wide Changes**: + Repository-wide restructurings or standard bumps may occasionally omit the subsystem prefix (e.g. `Move codebase from C99 to C17`, `Bump version to 10.0`, `Reorganize codebase with new directories`), but scoped changes should always use the subsystem prefix. + +2. **Subject Line**: + - **Format**: `: ` (separated by a colon and a single space). + - **Casing**: Start the summary with a lowercase letter (e.g. `libflow: drop a magic number`, `f3write: track per-file min/max speeds`), unless the first word is a case-sensitive code identifier, macro, or proper noun (e.g. `README: improve instructions for FreeBSD`, `libutils: add generic macro MIN()`). + - **Mood**: Use the imperative mood (e.g. `add`, `fix`, `drop`, `make`, `avoid`, `replace`, `adopt`, `employ`, `update`, `simplify`, `standardize`, `rename`, `convert`, `tighten`, `generalize`, `remove`, not `added`, `fixes`, `updating`). + - **Punctuation**: Do not end the subject line with a period. + - **Length**: Keep the subject line concise (under 72 characters, ideally 50–60 characters). + - **Function and Symbol References**: When mentioning functions or commands in the subject, adhere to the reference rules below (e.g. `f3brew: drop assert() in validate_block()`, `libprobe: make find_first_bad_block() report more information`). + +3. **Function, Command, and Symbol References**: + - **Internal / Project Functions**: + Always append empty parentheses `()` to function names and function-like macros: + - Examples: `init_flow()`, `validate_block()`, `calc_avg_speed()`, `find_first_bad_block()`, `end_measurement()`, `assert()`, `MIN()`, `DIM()`. + - **Standard Library Functions, System Calls, and System Commands**: + Always append the manual section number in parentheses after the name of standard library functions, POSIX functions, system calls, and system administration commands: + - **Section 1 (User Commands)**: `ls(1)`, `grep(1)` + - **Section 2 (System Calls)**: `clock_gettime(2)`, `fdatasync(2)`, `read(2)`, `write(2)`, `getrandom(2)` + - **Section 3 (C / Library Functions)**: `free(3)`, `aligned_alloc(3)`, `snprintf(3)`, `perror(3)` + - **Section 8 (System Administration Commands)**: `losetup(8)`, `mount(8)` + - **Types, Structs, and Macros**: + Mention types with their C specifiers (e.g. `struct flow`, `struct perf_device`, `struct block_stats`, `uint64_t`), enum values in lowercase with prefix (e.g. `bs_changed`, `bs_good`, `bs_overwritten`), and macros/constants in uppercase (e.g. `SECTOR_ORDER`, `MEGABYTE_ORDER`, `UNUSED()`, `DIM()`, `FW_STEADY`). + - **Parameters and Flags**: + Mention CLI flags as written (e.g. `--max-write-rate`, `--verbose`, `--destructive`, `--fix-cmd`). Mention function parameters by name (e.g. `parameter measurement_boundary`, `parameter processed_blocks`). + - **Plain Text Style**: + Do not use Markdown backticks in commit messages. Write code identifiers, function names, file names, compiler options (e.g. `-O2`), and directives (e.g. `#include `) as plain text. Single quotes (`'...'`) or double quotes (`"..."`) may be used for quoting exact phrases or compiler messages when clarity is needed. + +4. **Message Body**: + - **Separation**: Separate the subject from the body with a blank line. + - **Line Wrapping**: Hard-wrap all body lines at 72 characters. + - **Structure**: + - State the problem, limitation, or background context first (e.g. what fails, what distortion happens, or why the current behavior is inadequate). + - State the solution and technical rationale (what changed and why). + - **Lists**: When breaking down multiple steps or changes, use numbered lists (`1. ...`, `2. ...`) or bullet points (`- ...`). + - **Diagnostics**: Compiler warnings, error messages, and log snippets may be included verbatim in the body to document the issue clearly. + +5. **Issue References**: + - **Closing Issues**: When closing an issue, use the project's standard formula at the end of the body (separated by a blank line): + ```text + This commit closes # + ``` + or: + ```text + This patch closes # + ``` + - **Closing Multiple Issues**: + ```text + This commit closes #, closes # + ``` + - **Non-Closing References**: When referencing an issue without closing it: + ```text + See issue # for an example. + ``` + or: + ```text + This patch addresses issue #. + ``` + +### Example 1: Function name with `()` and parameter rationale +```text +libflow: add parameter measurement_boundary to end_measurement() + +Introduce parameter measurement_boundary to end_measurement(), +pass true in f3write.c and f3read.c since they make measurements +on files (i.e., a file is a measurement boundary), and pass +false for everyone else. + +Reaching a boundary forces any leftover processed_blocks and +acc_delay_ns to be committed to the global statistics. +This prevents measurement data from bleeding across boundaries. +``` + +### Example 2: System call with section number and issue resolution +```text +f3write: gracefully handle failures of fdatasync(2) + +According to issue #102, calls to fdatasync(2) might take +a long time (e.g. 3s or 4s) and distort the measurement of +the average write speed. This patch addresses it by only updating +the measurements when delays are within a tolerance. + +This patch closes #102 +``` + +### Example 3: CLI flag with motivation and issue reference +```text +f3brew: add flag --fix-cmd + +When flag --fix-cmd is passed, f3brew shows how to call f3fix on +the largest good region identified. +``` + +### Example 4: Compiler warning / diagnostics verbatim in body +```text +f3probe: avoid compiler warning + +When using -O2, GCC was issuing the following warning: + +f3probe.c: In function 'main': +f3probe.c:446:13: warning: 'sdev' may be used uninitialized in this function [-Wmaybe-uninitialized] + sdev_flush(sdev); + ^ + +GCC could not deduce that args->save being true implied +sdev was not NULL. + +This patch addresses issue #34. +``` + +### Example 5: Multi-tool change with numbered list +```text +f3write/f3read/f3brew: standardize report of I/O speeds + +This commit makes f3write, f3read, and f3brew report I/O speeds +analogously to f3probe: +1. Emphasizing that these are sequential measurements. +2. Including the number of blocks and time measured. +3. Using "write" and "read" instead of "writing" and "reading". +``` From 53691af3b08375094293da3b7607f943d20d5082 Mon Sep 17 00:00:00 2001 From: Michel Machado Date: Mon, 21 Sep 2026 20:34:48 -0400 Subject: [PATCH 4/5] agents: clarify brace placement in coding style skill The coding style rule previously stated that opening braces should always be on the same line, including for function definitions. However, throughout the entire repository, function definitions place the opening brace on a new line at column 0, following classic K&R and Linux kernel style. Update the braces rule to distinguish control statements and struct definitions from function definitions. --- .agents/skills/coding-style/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.agents/skills/coding-style/SKILL.md b/.agents/skills/coding-style/SKILL.md index c719b8c..2999406 100644 --- a/.agents/skills/coding-style/SKILL.md +++ b/.agents/skills/coding-style/SKILL.md @@ -14,7 +14,7 @@ When generating, modifying, or reviewing C code in the F3 project, follow these ## 2. Formatting and Indentation - **Indentation**: Uses **Tabs** for indentation. -- **Braces**: K&R style. Opening braces `{` are on the same line as the statement (`if`, `while`, `for`, `switch`, `struct`, and function definitions). +- **Braces**: K&R style. Opening braces `{` are on the same line for control statements (`if`, `while`, `for`, `switch`) and `struct` definitions, but on a new line at column 0 for function definitions. - **Whitespace**: - Space after keywords (`if`, `while`, `for`, `switch`, `do`). - No space between function name and the opening parenthesis `(`. From 7cbf12b0ca991a0f1103e09856c655ba83b95097 Mon Sep 17 00:00:00 2001 From: Michel Machado Date: Mon, 21 Sep 2026 20:53:16 -0400 Subject: [PATCH 5/5] Adopt -Wdeclaration-after-statement and fix code style Under -std=c17, GCC's -pedantic flag no longer warns about mixed declarations and code because C99 and later standards permit them. Add -Wdeclaration-after-statement to CFLAGS in Makefile to enforce the coding style rule that variables must be declared at the beginning of their scope. Address this and other code style violations: 1. In f3write.c and f3read.c, move variable declarations to the beginning of block scopes to satisfy -Wdeclaration-after-statement. 2. In f3fix.c, drop the space before the opening parenthesis of main(). 3. In libutils.h, remove the // comment within the documentation block comment and fix a typo. --- Makefile | 2 +- src/f3fix.c | 2 +- src/f3read.c | 4 +++- src/f3write.c | 4 +++- src/libutils.h | 3 +-- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 829eb5a..b213557 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC ?= gcc -CFLAGS += -std=c17 -Wall -Wextra -pedantic -MMD -ggdb +CFLAGS += -std=c17 -Wall -Wextra -pedantic -Wdeclaration-after-statement -MMD -ggdb BUILD_DIR = build SRC_DIR = src diff --git a/src/f3fix.c b/src/f3fix.c index 38f3dac..62cf19a 100644 --- a/src/f3fix.c +++ b/src/f3fix.c @@ -238,7 +238,7 @@ static int fix_disk(PedDevice *dev, PedDiskType *type, return ret; } -int main (int argc, char *argv[]) +int main(int argc, char *argv[]) { struct args args = { /* Defaults. */ diff --git a/src/f3read.c b/src/f3read.c index 63ca104..0320f69 100644 --- a/src/f3read.c +++ b/src/f3read.c @@ -314,6 +314,8 @@ static void validate_file(struct flow *fw, struct dynamic_buffer *dbuf, } else if (file_time_ns > 0) { const uint64_t blocks_read = stats->bytes_read >> block_order; + const char *unit; + assert((stats->bytes_read & (block_size - 1)) == 0); if (file_tot_blocks == blocks_read && file_tot_time_ns > 0) { @@ -321,7 +323,7 @@ static void validate_file(struct flow *fw, struct dynamic_buffer *dbuf, } file_avg_speed = calc_avg_speed(block_order, blocks_read, file_time_ns); - const char *unit = adjust_unit(&file_avg_speed); + unit = adjust_unit(&file_avg_speed); printf(" Avg: %.2f %s/s", file_avg_speed, unit); } } diff --git a/src/f3write.c b/src/f3write.c index bc06ed2..facd8cc 100644 --- a/src/f3write.c +++ b/src/f3write.c @@ -280,13 +280,15 @@ static int create_and_fill_file(struct flow *fw, struct dynamic_buffer *dbuf, } else if (file_time_ns > 0) { const uint64_t blocks_written = total_file_blocks - remaining_blocks; + const char *unit; + if (file_tot_blocks == blocks_written && file_tot_time_ns > 0) { file_time_ns = file_tot_time_ns; } file_avg_speed = calc_avg_speed(block_order, blocks_written, file_time_ns); - const char *unit = adjust_unit(&file_avg_speed); + unit = adjust_unit(&file_avg_speed); printf("OK! Avg: %.2f %s/s\n", file_avg_speed, unit); } else { diff --git a/src/libutils.h b/src/libutils.h index 938e241..e09333a 100644 --- a/src/libutils.h +++ b/src/libutils.h @@ -64,10 +64,9 @@ int nsec_to_str(uint64_t nsec, char *str); /* * The functions align_head() and align_mem() are used to align pointers. * - * The following example allocates two block on stack and makes sure that + * The following example allocates two blocks on stack and makes sure that * the blocks are aligned with the block size. * - * // The number 2 below means two blocks. * char stack[align_head(block_order) + (2 << block_order)]; * char *stamp_blk, *probe_blk; * stamp_blk = align_mem(stack, block_order);