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
81 changes: 78 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,83 @@

## Safe Chain

Package installs in this environment go through Aikido Safe Chain shims. Never bypass them:
Aikido Safe Chain shims examine each package that a package manager installs in this environment.
Never bypass the shims.

- Keep `~/.safe-chain/shims` first on `PATH`.
- Do not call unshimmed `npm`, `pnpm`, `npx`, or `pnpx`.
- Do not install packages with `curl | sh` or by pointing at a package manager outside the shim directory.
- Run `npm`, `npx`, `pnpm`, and `pnpx` only through the shims. Do not run a different copy by its
full path.
- Do not install a package with `curl | sh` or with a package manager that has no shim.
- If Safe Chain blocks a package, stop. Do not use a different command, path, or package to get the
same code. Tell the user the package name and the Safe Chain message.

## Simplified Technical English

Write in ASD-STE100 Simplified Technical English (STE). Get the current issue of the specification
free of charge from <https://www.asd-ste100.org>. STE applies to all text that you write for this
repository, its pull requests, and its issues. This text includes documentation, code comments,
commit messages, review replies, and changelog entries.

- Use approved STE words with their approved meanings. You can also use technical names and
technical verbs. If you cannot confirm that a word is approved, use a short, common word with one
meaning.
- Use one word for one meaning.
- Write an instruction in the imperative. Write one instruction in each sentence.
- Do not write more than 20 words in an instruction or 25 words in a descriptive sentence.
- Use the active voice.
- Use only the simple present, simple past, or simple future tense. Do not use the present perfect.
- Do not use the "-ing" form of a verb, except in a technical name.
- Do not write a noun cluster of more than three words.
- Do not omit articles, verbs, or subjects to make a sentence shorter.
- Write one topic in each paragraph. Do not write more than six sentences in a paragraph.
- Use a vertical list for steps, conditions, and other complex text.
- Do not change code, commands, identifiers, file paths, or quoted text to make them STE.
- Use STE for the text that you add or change. Do not rewrite other text only to make it STE.

## Test audit

Apply this gate to each test that a pull request adds, changes, or deletes. Apply it before you open
or update the pull request. This gate is the authoring gate of the `test-audit` skill in
`jaredwray/agentic`. If that skill is installed, use it.

Keep a new or changed test only if you can answer all four questions:

1. Which observable behavior, invariant, or contract does the test protect?
2. Which credible regression makes the test fail?
3. Why does the current coverage not find that regression? If a test or its table owns the
contract, extend it. Do not add a near-duplicate test.
4. Does the test need an export, flag, or hook that no production caller uses? If yes, test at the
real boundary.

- A regression test for a bug fix must fail on the code before the fix, for the intended reason.
- Do not keep a test that asserts nothing, restates the implementation, repeats the type checker,
or only proves a mock.
- A coverage target does not lower this bar. Reach an uncovered line through its public entry
point. If no caller can reach a branch, remove the branch. Do not add a test for it.
- Delete a test only when a different test proves its contract, or when the contract is gone. Do
not delete a test because it fails.
- Record the gate in the verification list of the pull request body. List each test that you did
not keep, rewrote, or deleted, and give the reason. For a deleted test, name the test that proves
its contract, or show that the contract is gone.
- Do not audit tests that this pull request does not touch. Audit them in a separate pull request.

## Pull requests

The task does not stop when you open a pull request. Do these steps before you start a different
task:

1. Wait approximately 20 minutes for automated and human code reviews.
2. Read each new comment. Find each comment that has a finding, a question, or a change request.
3. Examine the code for each finding or change request. Decide if it is correct. Do not decide from
who the reviewer is.
4. If it is correct, change the code. Run the same checks that CI runs. Push the change. On the
thread, reply with what changed and the commit SHA.
5. If it is not correct, reply on the thread with the reason. Give the file and line. Do not
resolve the thread. The reviewer closes it.
6. If a comment asks a question, answer it on the thread.
7. If CI fails, find the root cause and fix it. Do not skip or disable a test to make CI pass.
8. If you pushed a change or CI did not finish, do steps 1 to 7 again. Stop when CI passes and each
finding, question, and change request has a reply.

Do not reply to a comment that needs no answer: your own replies, approvals, thanks, and bot status
notices. A reply to one of these comments starts the loop again.
39 changes: 28 additions & 11 deletions scripts/setup-cloud-environment.sh
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env bash
# setup-cloud-environment.sh — Aikido Safe Chain bootstrap for Codespaces and Cursor Cloud Agents.
# setup-cloud-environment.sh — Aikido Safe Chain bootstrap for Codespaces, Cursor Cloud Agents,
# Claude Code on the web, and Codex cloud.
#
# Fail closed: never install dependencies unless Safe Chain shims are on PATH.
# Copied into the target repo as scripts/setup-cloud-environment.sh.
Expand All @@ -12,6 +13,32 @@ SAFE_CHAIN_INSTALLER_URL="https://github.com/AikidoSec/safe-chain/releases/downl
SAFE_CHAIN_SHIMS="${HOME}/.safe-chain/shims"
SAFE_CHAIN_BIN="${HOME}/.safe-chain/bin"

persist_shim_path() {
local rc="$1"
local line="export PATH=\"${SAFE_CHAIN_SHIMS}:${SAFE_CHAIN_BIN}:\$PATH\""
if [[ -f "$rc" ]] && grep -Fqx -- "$line" "$rc"; then
return 0
fi
Comment on lines +19 to +21

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Using grep -Fqx with the exact expanded path ($line) is prone to false negatives. For example, if a developer uses $HOME or ~ instead of the absolute path (e.g., export PATH="$HOME/.safe-chain/shims..."), or if there are minor formatting differences (such as trailing comments or different quoting), grep -Fqx will fail to match and the script will repeatedly append duplicate export lines to the startup files (like .bashrc or .profile). Reverting to a more flexible check, such as checking for the presence of .safe-chain/shims in the file, prevents duplicate entries.

Suggested change
if [[ -f "$rc" ]] && grep -Fqx -- "$line" "$rc"; then
return 0
fi
if [[ -f "$rc" ]] && grep -Fq ".safe-chain/shims" "$rc"; then
return 0
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This file is a verbatim copy of skills/security/defense-in-depth-nodejs/scripts/setup-cloud-environment.sh at ea156c03785398c8c156caa046ca954595f396c8. That revision replaced grep -Fq ".safe-chain/shims" with the exact-line check at scripts/setup-cloud-environment.sh:19. A substring match treats any mention of .safe-chain/shims as already configured, including a comment or a different PATH order. Changing it here would make this copy diverge from upstream again.

mkdir -p "$(dirname "$rc")"
printf '\n# Aikido Safe Chain shims\n%s\n' "$line" >> "$rc"
}

# Claude Code starts each Bash command from a shell snapshot taken at launch, not the rc files,
# and runs CLAUDE_ENV_FILE before every command instead. A failed SessionStart hook does not stop
# the session, so the shims go on its PATH before anything here can fail, holding stubs that
# refuse to run until Safe Chain's setup-ci replaces them.
if [[ -n "${CLAUDE_ENV_FILE:-}" ]]; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Add the Claude SessionStart hook

In Claude Code on the web, this block runs only if another hook starts the script. The target tree has no tracked .claude hook or other Claude caller. Thus, later package-manager commands can bypass Safe Chain. Add and track the SessionStart hook.

AGENTS.md reference: AGENTS.md:L42-L50

Useful? React with 👍 / 👎.

mkdir -p "$SAFE_CHAIN_SHIMS"
for cmd in npm npx pnpm pnpx; do
if [[ ! -e "${SAFE_CHAIN_SHIMS}/${cmd}" ]]; then
printf '#!/bin/sh\necho "error: Safe Chain is not set up, so %s is blocked; run bash ./scripts/setup-cloud-environment.sh" >&2\nexit 1\n' \
"$cmd" > "${SAFE_CHAIN_SHIMS}/${cmd}"
Comment on lines +33 to +35

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Do not treat the blocker stub as pnpm

When a prior Claude setup stops before Corepack creates pnpm, the next command sources the persisted shim path. command -v pnpm then finds this blocker, so the Corepack branch does not run. Safe Chain replaces the blocker but has no real pnpm for pnpm install, so setup cannot recover. Ignore this stub during the pnpm prerequisite check.

Useful? React with 👍 / 👎.

chmod +x "${SAFE_CHAIN_SHIMS}/${cmd}"
fi
done
persist_shim_path "$CLAUDE_ENV_FILE"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Run setup-ci when Safe Chain is already installed

When Safe Chain 1.5.15 already exists from normal setup, the installer exits before it runs setup-ci. These new blocker files remain in the persisted path, so pnpm safe-chain-verify stops instead of using Safe Chain. Run safe-chain setup-ci even when the installer reports the same version.

AGENTS.md reference: AGENTS.md:L42-L47

Useful? React with 👍 / 👎.

fi

if git_root=$(git rev-parse --show-toplevel 2>/dev/null); then
cd "$git_root"
fi
Expand Down Expand Up @@ -50,16 +77,6 @@ echo "${SAFE_CHAIN_INSTALLER_SHA256} ${installer}" | sha256sum -c -

export PATH="${SAFE_CHAIN_SHIMS}:${SAFE_CHAIN_BIN}:${PATH}"

persist_shim_path() {
local rc="$1"
local line="export PATH=\"${SAFE_CHAIN_SHIMS}:${SAFE_CHAIN_BIN}:\$PATH\""
if [[ -f "$rc" ]] && grep -Fq ".safe-chain/shims" "$rc"; then
return 0
fi
mkdir -p "$(dirname "$rc")"
printf '\n# Aikido Safe Chain shims\n%s\n' "$line" >> "$rc"
}

persist_shim_path "${HOME}/.profile"
persist_shim_path "${HOME}/.bashrc"
persist_shim_path "${HOME}/.zshrc"
Expand Down
Loading