Initial commit

Agent instructions (AGENTS.md), oxfmt config, git workflow skill,
and .gitignore for the C++ course repository.

Co-authored-by: Qwen 3.8 27B <qwen3.8_27b-q3_k_xl@jelly.nrv.nu>
This commit is contained in:
Pratchaya Khansomboon
2026-10-03 15:01:32 +02:00
co-authored by Qwen 3.8 27B
commit 2bb43ddbf9
5 changed files with 673 additions and 0 deletions
+220
View File
@@ -0,0 +1,220 @@
---
name: git
description: >-
Git workflow: commit message format, co-author trailers, tagging, and
branching conventions. Use when committing changes, creating release tags, or
following branch naming rules.
---
# Git Skill
This skill defines the git workflow for the repository: commit message format,
co-author trailers, tagging, and branching conventions.
## Commit Messages
Follow [Conventional Commits v1.0.0][cc] with the 50/72 rule. The full
specification is vendored in `spec.md` next to this file; read it for edge cases
such as scopes, footers, and breaking changes.
[cc]: https://www.conventionalcommits.org/en/v1.0.0/
### Format
```
<type>[optional scope][!]: <subject>
<body>
[BREAKING CHANGE: <description>]
Co-authored-by: <Name> <email>
```
- Subject: max 50 characters; use imperative mood and no period.
- Wrap body lines at 72 characters. Keep the message concise.
- Separate the subject from the body with a blank line.
- Use Conventional Commit types such as `feat`, `fix`, `docs`, `chore`, and
`ci`; scopes are optional.
- Mark breaking changes with `!` and/or a `BREAKING CHANGE:` footer.
- No em dashes (`—`). Use a colon or rewrite the sentence.
Always include one `Co-authored-by:` trailer per contributing agent or model,
using `<Name> <email>`:
- Name: human-readable model name, e.g. `Qwen 3.8 27B`.
- Email local part: lowercase model identifier including size, followed by `-`
and the quantization (the dash marks where the quant starts), e.g.
`qwen3.8_27b-q3_k_xl`. Replace other invalid characters with dots. If the
model is unknown, use the product name.
- Email domain: the service that ran the model, using its real domain. For
self-hosted services, use your own domain. Use `<runtime>.local` only for
local inference with no service domain.
Examples:
```
Co-authored-by: Qwen 3.8 27B <qwen3.8_27b-q3_k_xl@lmstudio.local>
Co-authored-by: GPT-5.6 Luna <gpt5.6.luna@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <claude.sonnet4.5@github.com>
```
The corporate commit-msg hook rejects these trailers, agent email addresses,
`.local` domains, and free-text descriptions. Skip the hook with `--no-verify`
when committing.
### Types
| Type | Use |
| ---------- | ---------------------------------- |
| `feat` | New feature or module |
| `fix` | Bug fix |
| `docs` | Documentation only |
| `chore` | Build, deps, config, housekeeping |
| `ci` | CI/CD changes |
| `refactor` | Code change without feature or fix |
| `test` | Adding or changing tests |
| `style` | Formatting, whitespace, semicolons |
### Examples
Good:
```
feat: add pointer arithmetic exercise
Add the pointer arithmetic exercise with a reference solution and
compilation checks for the expected output.
Co-authored-by: GPT-5.6 Luna <gpt5.6.luna@openrouter.ai>
```
```
docs: outline lecture 03 on memory layout
Document the stack, heap, and static storage regions so the exercise
solutions reference the same terminology.
Co-authored-by: GPT-5.6 Luna <gpt5.6.luna@openrouter.ai>
```
```
chore: add oxfmt config
Co-authored-by: GPT-5.6 Luna <gpt5.6.luna@openrouter.ai>
```
Bad:
```
added a new thing # no type, lowercase, vague
feat: add input trim # no body for a significant change
feat: add input trim control. # trailing period
feat: add trim — it's fast # em dash not allowed
```
## Committing
Stage changes:
```sh
git add -A
```
Write the complete message, including co-author trailers, to a message file,
then commit while skipping the rejecting hook:
```sh
git commit --no-verify -F <message-file>
```
## Tagging
This project uses semantic versioning for releases.
### Creating a tag
Create the tag:
```sh
git tag -a v0.1.0 -m "Release v0.1.0"
```
Push the tag:
```sh
git push origin v0.1.0
```
Tag messages follow the same rules as commit messages: no em dashes, wrapped at
72 characters.
### Tag naming
| Version | Meaning |
| -------- | ---------------------------------- |
| `v0.x.0` | Minor changes, breaking API |
| `v0.x.y` | Patch changes, backward-compatible |
| `v1.x.0` | Major release |
### When to tag
- After merging a feature branch with significant changes
- Before sharing course material with students
- After build system or project structure changes
### Listing tags
```sh
git tag -l
```
### Deleting a tag
Delete the local tag:
```sh
git tag -d v0.1.0
```
Remove the remote tag:
```sh
git push origin --delete v0.1.0
```
## Branching
For local development:
```sh
git checkout -b feat/add-counter
```
Branch naming:
| Prefix | Use |
| -------- | ------------- |
| `feat/` | New feature |
| `fix/` | Bug fix |
| `chore/` | Housekeeping |
| `docs/` | Documentation |
## Common Commands
| Command | Use |
| ----------------------- | --------------------------------- |
| `git log --oneline -10` | Recent history |
| `git diff --staged` | Check staged changes |
| `git status` | Current state |
| `git reset HEAD~1` | Undo last commit (keep changes) |
| `git rebase -i HEAD~3` | Interactive rebase last 3 commits |
## Checklist Before Committing
- [ ] Markdown changes pass: `npx oxfmt --check .`
- [ ] Commit message follows 50/72 rule
- [ ] Conventional commit type used
- [ ] Co-author trailer for every contributing agent or model
- [ ] No em dashes
- [ ] No large unchanged regions reformatted
- [ ] No speculative code or unused imports
+254
View File
@@ -0,0 +1,254 @@
# Conventional Commits 1.0.0
A specification for adding human and machine readable meaning to commit
messages.
- Source: <https://www.conventionalcommits.org/en/v1.0.0/>
- License: Creative Commons - CC BY 3.0
## Summary
The Conventional Commits specification is a lightweight convention on top of
commit messages. It provides an easy set of rules for creating an explicit
commit history; which makes it easier to write automated tools on top of. This
convention dovetails with SemVer, by describing the features, fixes, and
breaking changes made in commit messages.
The commit message should be structured as follows:
```text
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
```
The commit contains the following structural elements, to communicate intent to
the consumers of your library:
- `fix`: a commit of the type fix patches a bug in your codebase (this
correlates with PATCH in Semantic Versioning).
- `feat`: a commit of the type feat introduces a new feature to the codebase
(this correlates with MINOR in Semantic Versioning).
- `BREAKING CHANGE`: a commit that has a footer `BREAKING CHANGE:`, or appends a
`!` after the type/scope, introduces a breaking API change (correlating with
MAJOR in Semantic Versioning). A BREAKING CHANGE can be part of commits of any
type.
- Types other than `fix:` and `feat:` are allowed. For example,
@commitlint/config-conventional (based on the Angular convention) recommends
`build:`, `chore:`, `ci:`, `docs:`, `style:`, `refactor:`, `perf:`, `test:`,
and others.
- Footers other than `BREAKING CHANGE: <description>` may be provided and follow
a convention similar to git trailer format.
Additional types are not mandated by the Conventional Commits specification, and
have no implicit effect in Semantic Versioning (unless they include a BREAKING
CHANGE). A scope may be provided to a commit’s type, to provide additional
contextual information and is contained within parenthesis, e.g.,
`feat(parser): add ability to parse arrays`.
## Examples
### Commit message with description and breaking change footer
```text
feat: allow provided config object to extend other configs
BREAKING CHANGE: `extends` key in config file is now used for extending other config files
```
### Commit message with ! to draw attention to breaking change
```text
feat!: send an email to the customer when a product is shipped
```
### Commit message with scope and ! to draw attention to breaking change
```text
feat(api)!: send an email to the customer when a product is shipped
```
### Commit message with both ! and BREAKING CHANGE footer
```text
feat!: drop support for Node 6
BREAKING CHANGE: use JavaScript features not available in Node 6.
```
### Commit message with no body
```text
docs: correct spelling of CHANGELOG
```
### Commit message with scope
```text
feat(lang): add Polish language
```
### Commit message with multi-paragraph body and multiple footers
```text
fix: prevent racing of requests
Introduce a request id and a reference to latest request. Dismiss
incoming responses other than from latest request.
Remove timeouts which were used to mitigate the racing issue but are
obsolete now.
Reviewed-by: Z
Refs: #123
```
## Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”,
“SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be
interpreted as described in RFC 2119.
- Commits MUST be prefixed with a type, which consists of a noun, `feat`, `fix`,
etc., followed by the OPTIONAL scope, OPTIONAL `!`, and REQUIRED terminal
colon and space.
- The type `feat` MUST be used when a commit adds a new feature to your
application or library.
- The type `fix` MUST be used when a commit represents a bug fix for your
application.
- A scope MAY be provided after a type. A scope MUST consist of a noun
describing a section of the codebase surrounded by parenthesis, e.g.,
`fix(parser):`.
- A description MUST immediately follow the colon and space after the type/scope
prefix. The description is a short summary of the code changes, e.g.,
`fix: array parsing issue when multiple spaces were contained in string`.
- A longer commit body MAY be provided after the short description, providing
additional contextual information about the code changes. The body MUST begin
one blank line after the description.
- A commit body is free-form and MAY consist of any number of newline separated
paragraphs.
- One or more footers MAY be provided one blank line after the body. Each footer
MUST consist of a word token, followed by either a `:<space>` or `<space>#`
separator, followed by a string value (this is inspired by the git trailer
convention).
- A footer’s token MUST use `-` in place of whitespace characters, e.g.,
`Acked-by` (this helps differentiate the footer section from a multi-paragraph
body). An exception is made for BREAKING CHANGE, which MAY also be used as a
token.
- A footer’s value MAY contain spaces and newlines, and parsing MUST terminate
when the next valid footer token/separator pair is observed.
- Breaking changes MUST be indicated in the type/scope prefix of a commit, or as
an entry in the footer.
- If included as a footer, a breaking change MUST consist of the uppercase text
BREAKING CHANGE, followed by a colon, space, and description, e.g.,
`BREAKING CHANGE: environment variables now take precedence over config files`.
- If included in the type/scope prefix, breaking changes MUST be indicated by a
`!` immediately before the `:`. If `!` is used, BREAKING CHANGE MAY be omitted
from the footer section, and the commit description SHALL be used to describe
the breaking change.
- Types other than feat and fix MAY be used in your commit messages, e.g.,
`docs: update ref docs`.
- The units of information that make up Conventional Commits MUST NOT be treated
as case-sensitive by implementors, with the exception of BREAKING CHANGE which
MUST be uppercase.
- BREAKING-CHANGE MUST be synonymous with BREAKING CHANGE, when used as a token
in a footer.
## Why Use Conventional Commits
- Automatically generating CHANGELOGs.
- Automatically determining a semantic version bump (based on the types of
commits landed).
- Communicating the nature of changes to teammates, the public, and other
stakeholders.
- Triggering build and publish processes.
- Making it easier for people to contribute to your projects, by allowing them
to explore a more structured commit history.
## FAQ
### How should I deal with commit messages in the initial development phase?
We recommend that you proceed as if you’ve already released the product.
Typically somebody, even if it’s your fellow software developers, is using your
software. They’ll want to know what’s fixed, what breaks etc.
### Are the types in the commit title uppercase or lowercase?
Any casing may be used, but it’s best to be consistent.
### What do I do if the commit conforms to more than one of the commit types?
Go back and make multiple commits whenever possible. Part of the benefit of
Conventional Commits is its ability to drive us to make more organized commits
and PRs.
### Doesn’t this discourage rapid development and fast iteration?
It discourages moving fast in a disorganized way. It helps you be able to move
fast long term across multiple projects with varied contributors.
### Might Conventional Commits lead developers to limit the type of commits
they make because they’ll be thinking in the types provided?
Conventional Commits encourages us to make more of certain types of commits such
as fixes. Other than that, the flexibility of Conventional Commits allows your
team to come up with their own types and change those types over time.
### How does this relate to SemVer?
fix type commits should be translated to PATCH releases. feat type commits
should be translated to MINOR releases. Commits with BREAKING CHANGE in the
commits, regardless of type, should be translated to MAJOR releases.
### How should I version my extensions to the Conventional Commits
Specification, e.g., @jameswomack/conventional-commit-spec?
We recommend using SemVer to release your own extensions to the specification
(and encourage you to make these extensions!).
### What do I do if I accidentally use the wrong commit type?
When you used a type that’s of the spec but not the correct type, e.g., `fix`
instead of `feat`: prior to merging or releasing the mistake, we recommend using
`git rebase -i` to edit the commit history. After release, the cleanup will be
different according to what tools and processes you use.
When you used a type not of the spec, e.g., `feet` instead of `feat`: in a worst
case scenario, it’s not the end of the world if a commit lands that does not
meet the Conventional Commits specification. It simply means that commit will be
missed by tools that are based on the spec.
### Do all my contributors need to use the Conventional Commits specification?
No! If you use a squash based workflow on Git, lead maintainers can clean up the
commit messages as they’re merged, adding no workload to casual committers. A
common workflow for this is to have your git system automatically squash commits
from a pull request and present a form for the lead maintainer to enter the
proper git commit message for the merge.
### How does Conventional Commits handle revert commits?
Reverting code can be complicated: are you reverting multiple commits? if you
revert a feature, should the next release instead be a patch?
Conventional Commits does not make an explicit effort to define revert behavior.
Instead we leave it to tooling authors to use the flexibility of types and
footers to develop their logic for handling reverts.
One recommendation is to use the `revert` type, and a footer that references the
commit SHAs that are being reverted:
```text
revert: let us never again speak of the noodle incident
Refs: 676104e, a215868
```
## License
Creative Commons - CC BY 3.0
+10
View File
@@ -0,0 +1,10 @@
# Build
build/
out/
*.o
*.obj
*.exe
# OS / editor
.DS_Store
Thumbs.db
+12
View File
@@ -0,0 +1,12 @@
{
"ignorePatterns": ["node_modules", "dist", ".git"],
"overrides": [
{
"files": ["*.md"],
"options": {
"printWidth": 80,
"proseWrap": "always"
}
}
]
}
+177
View File
@@ -0,0 +1,177 @@
# AGENTS.md
## Project Overview
This repository holds the content for a C++ course: lecture material, exercises,
and runnable code examples. The language target is modern C++ (C++23).
The repository is in a startup phase: no course content exists yet. As material
is added, document its layout under "Source Layout".
## Build System
No build system is set up yet. When one is added for the course examples,
document its configure, build, and test commands here.
## Coding Conventions
- **Language:** C++23
- **Primitive types:** use fixed-width type aliases (`u32`, `i64`, ...) instead
of `std::uint32_t` etc.
- **Trailing return type** for function signatures (e.g. `auto fn() -> void`)
- **4-space indentation**
- **No semicolons after closing braces** for namespaces/classes
- `auto` for obvious types (e.g. `auto main(...) -> int`)
- **East const** (e.g. `char const*` not `const char*`)
- **Trailing return type** for all function definitions, including operators
(e.g. `auto operator=(T&&) noexcept -> T&`)
- **Public members first** in class declarations, private members at the bottom
- **Private data members** start with `m_` (e.g. `m_state`)
- `<>` includes only for system headers (std, OS, etc.)
- `""` includes for third-party dependencies (e.g. `fmt`, `nlohmann/json`)
- **Naming:** `snake_case` for variables, functions, and classes
- **Naming:** `SCREAMING_SNAKE_CASE` only for macros and constants
- **Header extensions:** C++ headers use `.hpp`, C headers use `.h`
- Include order:
1. C++ standard library headers (`<chrono>`, `<vector>`, etc.)
2. _(blank line)_
3. C standard library headers (`<stdlib.h>`, `<string.h>`, etc.)
4. _(blank line)_
5. OS-specific headers (Windows API, POSIX, etc.)
6. _(blank line)_
7. Third-party dependencies (`"fmt/core.h"`, etc.)
8. _(blank line)_
9. Local/project headers
## Shell Scripts
- Always use `#!/bin/sh` shebang for shell scripts
- Scripts must be POSIX compliant (no bashisms)
- When providing commands to users:
- Windows/PowerShell: use `` ` `` for line continuation
- Unix/Linux/macOS: use `\` for line continuation
## Commit Messages
Follow the git skill (`.agents/skills/git/SKILL.md`) for commit message format,
conventional types, co-author trailers, and the committing workflow.
## Versioning
This project follows [Semantic Versioning](https://semver.org) for tagged
releases of the course material.
- **Patch** (`x.y.Z`): corrections and small updates to existing material. No
change is too small.
- **Minor** (`x.Y.z`): new lectures, exercises, or other significant additions.
- **Major** (`X.y.z`): restructuring that breaks how the material is organized
or used.
## Documentation (Markdown)
- Wrap normal text and lists at **max 80 columns** (for readability in terminals
and editors).
- **Exceptions**: Tables and code blocks (` ``` `) can exceed 80 columns when
formatting requires it (e.g. trees, alignment).
- Use standard Markdown: `**bold**`, `` `inline code` ``, `##` headings, `-` or
numbered lists, fenced code blocks with language hints (` ```cpp `,
` ```sh `).
- Keep examples concise, up-to-date, and self-documenting.
- This file (`AGENTS.md`) follows its own rules.
- Do not use em dashes (`—`). Use a colon or rewrite the sentence.
### Auto-Formatting with oxfmt
- All markdown files are formatted with **oxfmt**
- **Always run `npx oxfmt --write .` after editing any markdown file**
- This is mandatory. Do not skip it. Run it before finishing your response
- Use `npx oxfmt --check .` to verify formatting before committing
- Config is in `.oxfmtrc.json` at the project root
- Do not manually fight the formatter. Let oxfmt handle spacing, line breaks,
and list alignment
## Source Layout
```text
cppcourse/
AGENTS.md # This file
.oxfmtrc.json # oxfmt config
.agents/ # Agent skills (git workflow)
```
Course content (lectures, exercises, examples) will be added as the course is
developed. Document the layout here when it takes shape.
## Behavioral Guidelines
Reduce common LLM coding mistakes. These guidelines bias toward caution over
speed. For trivial tasks, use judgment.
### 1. Think Before Coding
Don't assume. Don't hide confusion. Surface tradeoffs.
Before implementing:
- State your assumptions explicitly. If uncertain, ask.
- If multiple interpretations exist, present them, don't pick silently.
- If a simpler approach exists, say so. Push back when warranted.
- If something is unclear, stop. Name what's confusing. Ask.
### 2. Simplicity First
Minimum code that solves the problem. Nothing speculative.
- No features beyond what was asked.
- No abstractions for single-use code.
- No "flexibility" or "configurability" that wasn't requested.
- No error handling for impossible scenarios.
- If you write 200 lines and it could be 50, rewrite it.
Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes,
simplify.
### 3. Surgical Changes
Touch only what you must. Clean up only your own mess.
When editing existing code:
- Don't "improve" adjacent code, comments, or formatting.
- Don't refactor things that aren't broken.
- Match existing style, even if you'd do it differently.
- If you notice unrelated dead code, mention it, don't delete it.
When your changes create orphans:
- Remove imports/variables/functions that YOUR changes made unused.
- Don't remove pre-existing dead code unless asked.
Every changed line should trace directly to the user's request.
### 4. Goal-Driven Execution
Define success criteria. Loop until verified.
Transform tasks into verifiable goals:
- "Add validation" means: write tests for invalid inputs, then make them pass.
- "Fix the bug" means: write a test that reproduces it, then make it pass.
- "Refactor X" means: ensure tests pass before and after.
For multi-step tasks, state a brief plan:
```
1. [Step] → verify: [check]
2. [Step] → verify: [check]
3. [Step] → verify: [check]
```
Strong success criteria let you loop independently. Weak criteria ("make it
work") require constant clarification.
## Target Platforms
The primary platform for building and running course examples is Linux. Keep
examples portable within that constraint unless a lesson specifically targets
another platform.