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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: Security reports
url: https://github.com/tinyhumansai/rust-template/security/policy
url: https://github.com/tinyhumansai/tinytools/security/policy
about: Please do not report vulnerabilities through public issues.
81 changes: 58 additions & 23 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ jobs:
# This job executes repository code (cargo build/test); don't persist
# the token in git config.
persist-credentials: false
Comment thread
senamakel marked this conversation as resolved.
submodules: recursive

- uses: dtolnay/rust-toolchain@stable
with:
Expand All @@ -53,32 +52,71 @@ jobs:
- name: Test default features
run: cargo test

# `cargo build --all-targets` only *compiles* an example. `AGENTS.md`
# promises `cargo run -p template --example basic` works, and a compiled
# example can still fail on its first line.
- name: Run the bundled example
run: cargo run -p template --example basic

# `crates/template-bus` exists so a host can name the payload types
# without compiling the module. That promise is invisible in a diff,
# because a forbidden dependency arrives transitively through a feature
# someone enabled one crate away — so it is asserted rather than
# documented.
# This crate is the vocabulary both an agent harness and a host
# application link against, so its dependency list is a promise to both.
# That promise is invisible in a diff, because a forbidden dependency
# arrives transitively through a feature someone enabled one crate away —
# so it is asserted rather than documented.
#
# The FORWARD form is required. `cargo tree -i <crate> -p template-bus`
# `tinyagents` is on the list for a structural reason, not a size one: it
# depends on *this* crate. An edge back would be a cycle, and the
# `context` module's erasure trait exists precisely to make one
# unnecessary. Everything else on the list is weight a tool author should
# not have to compile to write a tool.
#
# The FORWARD form is required. `cargo tree -i <crate> -p tinytools`
# discards the `-p` scope, prints the whole-workspace inverse tree, and
# exits 0 looking clean even when this crate is the one at fault.
- name: Assert the contract crate stays transport-free
- name: Assert the vocabulary crate stays dependency-light
run: |
set -euo pipefail
forbidden="$(cargo tree -p template-bus -e normal,build --prefix none \
| grep -Ei 'tinybus|tokio|reqwest|ureq|hyper|rusqlite|git2' || true)"
# Compare crate NAMES only. `cargo tree` prints each package as
# `name vX.Y.Z (/path/to/checkout)`, and a consumer may vendor this
# repository *underneath* one of the forbidden crates — tinyagents
# does exactly that — so grepping the raw line matches the path and
# reports a dependency that is not there. Cut the version and path off
# first.
package_names="$(cargo tree -p tinytools --all-features -e normal,build --prefix none \
| awk '{print $1}' | sort -u)"

# An ALLOWLIST, not a blocklist: naming eight forbidden crates only
# catches those eight. Adding `surf`, `async-std`, an arbitrary
# `*-sys` native binding, or any other transport/runtime would pass
# silently under a blocklist. Every package this crate's forward tree
# is reviewed to actually contain is named here instead, so *any*
# newly introduced package — forbidden or merely unreviewed — fails
# the gate until this list is updated in the same commit.
allowed='
tinytools
anyhow
async-trait
serde
serde_core
serde_derive
serde_json
proc-macro2
quote
syn
unicode-ident
itoa
memchr
zmij
'

# Anything in package_names that is not a line of $allowed.
forbidden="$(comm -23 \
<(printf '%s\n' "$package_names") \
<(printf '%s\n' "$allowed" | sort -u))"

if [ -n "$forbidden" ]; then
echo "template-bus pulled in a dependency its manifest forbids:" >&2
echo "tinytools pulled in a dependency its manifest doesn't review for:" >&2
echo "$forbidden" >&2
echo >&2
echo "The contract is what a host compiles against. It must stay free" >&2
echo "of transports, async runtimes, HTTP clients and native libraries." >&2
echo "This crate is what a harness and a host both compile against." >&2
echo "It must stay free of agent harnesses, transports, async" >&2
echo "runtimes, HTTP clients and native libraries. If this package" >&2
echo "is a genuinely reviewed addition, add it to the allowlist in" >&2
echo "this step in the same commit that adds the dependency." >&2
exit 1
fi

Expand All @@ -100,7 +138,6 @@ jobs:
- uses: actions/checkout@v7
with:
persist-credentials: false
submodules: recursive

- uses: dtolnay/rust-toolchain@stable

Expand All @@ -118,7 +155,6 @@ jobs:
- uses: actions/checkout@v7
with:
persist-credentials: false
submodules: recursive

# `rust-version` is inherited from `[workspace.package]`, so every member
# reports the same value. Read it off the package the module ships as
Expand All @@ -128,7 +164,7 @@ jobs:
run: |
set -euo pipefail
msrv="$(cargo metadata --format-version 1 --no-deps \
| jq -r '.packages[] | select(.name == "template") | .rust_version')"
| jq -r '.packages[] | select(.name == "tinytools") | .rust_version')"
if [[ -z "$msrv" || "$msrv" == "null" ]]; then
echo "workspace.package.rust-version is not set in Cargo.toml" >&2
exit 1
Expand All @@ -151,7 +187,6 @@ jobs:
- uses: actions/checkout@v7
with:
persist-credentials: false
submodules: recursive

- name: Check advisories, licenses, bans, and sources
uses: EmbarkStudios/cargo-deny-action@v2
Expand Down
Loading