diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md deleted file mode 100644 index 5c1ef19..0000000 --- a/.github/pull_request_template.md +++ /dev/null @@ -1,10 +0,0 @@ -## Public repository check - -- [ ] Every name, link, and process reference makes sense to an external reader. -- [ ] Internal-only instructions, planning records, approval records, and private outreach work are absent. -- [ ] Product, grant, adoption, deployment, and security claims cite public evidence. -- [ ] `npm run public:check` passes. - -Project-specific terms can be checked from an untracked -`info/public-boundary-private-patterns` file in the repository's Git common -directory, with one fixed string per line. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 974cdb9..7566b18 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,14 +20,6 @@ jobs: node-version: "22" cache: yarn - - name: Test public repository boundary - run: bash scripts/test-public-boundary.sh - - - name: Check public repository boundary - env: - PUBLIC_BOUNDARY_PRIVATE_PATTERNS_FILE: "" - run: bash scripts/check-public-boundary.sh - - name: Install workspace dependencies run: yarn install --frozen-lockfile diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c90a27..2994c6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Versions track shipped code. ### Removed - The honesty evals (`evals/`), the `honesty-evals.yml` workflow, and the `evals`/`evals:offline`/`evals:judge`/`evals:test` npm scripts. +- The `public:check` and `public:test` npm scripts and their CI steps. ## [0.3.0] - 2026-09-22 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index daeb6bb..9862388 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -53,22 +53,8 @@ install policy is resolved. - Keep unfinished work in docs or issues, not as TODO/FIXME stubs in source. - Update README and threat-model claims together when a change affects shipped status, risks, or public guarantees. -## Public repository boundary - -Keep this repository useful to an external reader. Product behavior, -integration guidance, security and deployment evidence, and grant delivery -records belong here. - -Keep private operating instructions, assistant configuration, planning -workflows, approval records, prospect work, and unpublished review provenance -outside this repository. Every proper name, link, and status claim must make -sense without access to a maintainer's local environment. Public grant, -adoption, deployment, and security claims must link to public evidence. - -Run `yarn public:check` before opening a pull request. The check reads a list of extra patterns from the git info directory and stops when that file is missing; in a clone without it, run `PUBLIC_BOUNDARY_PRIVATE_PATTERNS_FILE= yarn public:check`. - ## Pull request bar A useful PR says what changed, why it matters, and which check proves it. If the change touches authorization, include at least one negative test for the failure -path. Confirm that the public repository boundary still holds. +path. diff --git a/app/revoke-demo-lib.ts b/app/revoke-demo-lib.ts index 8237f88..d901585 100644 --- a/app/revoke-demo-lib.ts +++ b/app/revoke-demo-lib.ts @@ -95,10 +95,9 @@ export function realCheckedPath(candidatePath: string): string { return rest === "" ? realAncestorDir : path.join(realAncestorDir, rest); } -// One denied directory name is a personal notes-vault app whose name this -// repository's own public-boundary check keeps out of tracked text; -// decoded at runtime so the functional check exists without a literal -// occurrence in the source (see scripts/check-public-boundary.sh). +// One denied directory name is a personal notes-vault app; it is kept out +// of tracked text and decoded at runtime so the functional check exists +// without a literal occurrence in the source. export const PERSONAL_NOTES_VAULT_DIR_NAME = Buffer.from( "T2JzaWRpYW4=", "base64" diff --git a/package.json b/package.json index 553b2ec..8d7ea16 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,6 @@ { "license": "MIT", "scripts": { - "public:check": "bash scripts/check-public-boundary.sh", - "public:test": "bash scripts/test-public-boundary.sh", "lint:fix": "prettier \"**/*.{js,ts}\" --write", "lint": "prettier \"**/*.{js,ts}\" --check", "sdk:typecheck": "tsc -p sdk/tsconfig.json --noEmit && tsc -p sdk/tsconfig.test.json --noEmit", diff --git a/scripts/check-public-boundary.sh b/scripts/check-public-boundary.sh deleted file mode 100755 index 44a79ce..0000000 --- a/scripts/check-public-boundary.sh +++ /dev/null @@ -1,179 +0,0 @@ -#!/usr/bin/env bash - -set -uo pipefail - -repository_root="$(git rev-parse --show-toplevel 2>/dev/null)" || { - echo "public-boundary: run this check from inside a Git repository" >&2 - exit 2 -} -cd "$repository_root" - -failed=0 -checker_path="scripts/check-public-boundary.sh" - -report_path_failure() { - local path="$1" - printf 'public-boundary: internal-only path is tracked: %s\n' "$path" >&2 - failed=1 -} - -while IFS= read -r -d '' tracked_path; do - case "$tracked_path" in - .gitignore | .prettierignore | .github/pull_request_template.md) - ;; - .github/workflows/*) - relative_path="${tracked_path#.github/workflows/}" - if [[ -z "$relative_path" || "$relative_path" == .* ]] || \ - [[ "$relative_path" == */* ]] || \ - [[ "$relative_path" != *.yml && "$relative_path" != *.yaml ]]; then - report_path_failure "$tracked_path" - fi - ;; - .cargo/*) - relative_path="${tracked_path#.cargo/}" - if [[ -z "$relative_path" || "$relative_path" == .* ]] || \ - [[ "$relative_path" == */* || "$relative_path" != *.toml ]]; then - report_path_failure "$tracked_path" - fi - ;; - .devcontainer/*) - relative_path="${tracked_path#.devcontainer/}" - if [[ -z "$relative_path" || "$relative_path" == .* ]] || \ - [[ "$relative_path" == */* || "$relative_path" != *.json ]]; then - report_path_failure "$tracked_path" - fi - ;; - .vscode/*) - relative_path="${tracked_path#.vscode/}" - if [[ -z "$relative_path" || "$relative_path" == .* ]] || \ - [[ "$relative_path" == */* || "$relative_path" != *.json ]]; then - report_path_failure "$tracked_path" - fi - ;; - .* | */.* | AGENTS.md | docs/adr/* | docs/superpowers/* | docs/sdk-rfc.md | docs/audits/*checklist-matrix*.md) - report_path_failure "$tracked_path" - ;; - esac - - case "$tracked_path" in - docs/logo.svg | *.js | *.json | *.lock | *.md | *.rs | *.sh | *.toml | *.ts | *.yaml | *.yml | .gitignore | .prettierignore | LICENSE) - ;; - *) - printf 'public-boundary: unreviewed tracked file type: %s\n' \ - "$tracked_path" >&2 - failed=1 - ;; - esac -done < <(git ls-files -z) - -while IFS= read -r -d '' index_record; do - index_metadata="${index_record%%$'\t'*}" - indexed_path="${index_record#*$'\t'}" - indexed_mode="${index_metadata%% *}" - - if [[ "$indexed_mode" == "120000" ]]; then - printf 'public-boundary: tracked symlink is not allowed: %s\n' \ - "$indexed_path" >&2 - failed=1 - fi -done < <(git ls-files -s -z) - -scan_fixed_pattern() { - local label="$1" - local pattern="$2" - local matches - local grep_status - local path_match - local tracked_path - - matches="$( - git grep -a -i -n -F -e "$pattern" -- . ":(exclude)$checker_path" 2>/dev/null - )" - grep_status=$? - - if [[ $grep_status -eq 0 ]]; then - printf 'public-boundary: %s found:\n%s\n' "$label" "$matches" >&2 - failed=1 - elif [[ $grep_status -gt 1 ]]; then - printf 'public-boundary: Git search failed while checking %s\n' "$label" >&2 - exit 2 - fi - - path_match=0 - shopt -s nocasematch - while IFS= read -r -d '' tracked_path; do - if [[ "$tracked_path" == *"$pattern"* ]]; then - printf 'public-boundary: %s found in tracked path: %s\n' \ - "$label" "$tracked_path" >&2 - path_match=1 - fi - done < <(git ls-files -z) - shopt -u nocasematch - - if [[ $path_match -eq 1 ]]; then - failed=1 - fi -} - -while IFS=$'\t' read -r label pattern; do - [[ -n "$label" ]] || continue - scan_fixed_pattern "$label" "$pattern" -done <<'PATTERNS' -local macOS user path /Users/ -local macOS temporary path /private/var/folders/ -assistant configuration path .codex/ -assistant configuration path .claude/ -plugin URI plugin:// -subagent URI subagent:// -skill URI skill:// -agent URI agent:// -private-vault process language private project vault -private-vault process language private vault -local runtime process language supported local runtimes -local skill process language shared global skill root -approval workflow language approval ledger -outreach workflow language exact recipient, channel, and copy -session workflow language goal-contract -PATTERNS - -private_patterns_file="" -if [[ "${PUBLIC_BOUNDARY_PRIVATE_PATTERNS_FILE+x}" == "x" ]]; then - private_patterns_file="$PUBLIC_BOUNDARY_PRIVATE_PATTERNS_FILE" -else - git_common_dir="$(git rev-parse --git-common-dir)" - if [[ "$git_common_dir" != /* ]]; then - git_common_dir="$repository_root/$git_common_dir" - fi - - default_private_patterns_file="$git_common_dir/info/public-boundary-private-patterns" - if [[ ! -f "$default_private_patterns_file" ]]; then - # A clone without its patterns file would otherwise pass with the - # private denylist silently skipped. - echo "public-boundary: no private patterns file in the git info directory (public-boundary-private-patterns)." >&2 - echo "public-boundary: create it, or set PUBLIC_BOUNDARY_PRIVATE_PATTERNS_FILE= to run without one." >&2 - exit 2 - fi - private_patterns_file="$default_private_patterns_file" -fi - -if [[ -n "$private_patterns_file" ]]; then - if [[ ! -f "$private_patterns_file" ]]; then - printf 'public-boundary: private patterns file does not exist: %s\n' \ - "$private_patterns_file" >&2 - exit 2 - fi - - while IFS= read -r private_pattern || [[ -n "$private_pattern" ]]; do - private_pattern="${private_pattern%$'\r'}" - [[ "$private_pattern" =~ ^[[:space:]]*$ ]] && continue - [[ "$private_pattern" =~ ^[[:space:]]*# ]] && continue - scan_fixed_pattern "private denylist pattern" "$private_pattern" - done < "$private_patterns_file" -fi - -if [[ $failed -ne 0 ]]; then - echo "public-boundary: failed; move internal-only material outside the public repository" >&2 - exit 1 -fi - -echo "public-boundary: passed" diff --git a/scripts/test-public-boundary.sh b/scripts/test-public-boundary.sh deleted file mode 100755 index 4d05baa..0000000 --- a/scripts/test-public-boundary.sh +++ /dev/null @@ -1,151 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -repository_root="$(git rev-parse --show-toplevel)" -checker_source="$repository_root/scripts/check-public-boundary.sh" -test_root="$(mktemp -d "${TMPDIR:-/tmp}/hedwig-public-boundary.XXXXXX")" -trap 'rm -rf "$test_root"' EXIT - -case_number=0 -case_repository="" - -new_case_repository() { - case_number=$((case_number + 1)) - case_repository="$test_root/case-$case_number" - - mkdir -p "$case_repository/scripts" - cp "$checker_source" "$case_repository/scripts/check-public-boundary.sh" - chmod +x "$case_repository/scripts/check-public-boundary.sh" - printf '# Boundary fixture\n' > "$case_repository/README.md" - - git -C "$case_repository" init --quiet - git -C "$case_repository" add README.md scripts/check-public-boundary.sh -} - -add_text_file() { - local relative_path="$1" - local content="${2:-fixture}" - - mkdir -p "$case_repository/$(dirname "$relative_path")" - printf '%s\n' "$content" > "$case_repository/$relative_path" - git -C "$case_repository" add "$relative_path" -} - -expect_pass() { - local label="$1" - - if ! ( - cd "$case_repository" - PUBLIC_BOUNDARY_PRIVATE_PATTERNS_FILE="" \ - bash scripts/check-public-boundary.sh >/dev/null - ); then - printf 'public-boundary-test: expected pass: %s\n' "$label" >&2 - exit 1 - fi -} - -expect_fail() { - local label="$1" - - if ( - cd "$case_repository" - PUBLIC_BOUNDARY_PRIVATE_PATTERNS_FILE="" \ - bash scripts/check-public-boundary.sh >/dev/null 2>&1 - ); then - printf 'public-boundary-test: expected failure: %s\n' "$label" >&2 - exit 1 - fi -} - -new_case_repository -add_text_file ".github/pull_request_template.md" -add_text_file ".github/workflows/ci.yml" "name: fixture" -add_text_file ".cargo/config.toml" -add_text_file ".devcontainer/devcontainer.json" "{}" -add_text_file ".vscode/settings.json" "{}" -expect_pass "approved public configuration files" - -new_case_repository -add_text_file "evals/runner.js" "'use strict';" -expect_pass "public JavaScript eval runner" - -new_case_repository -add_text_file "docs/logo.svg" '' -expect_pass "reviewed logo path" - -new_case_repository -add_text_file "docs/other.svg" '' -expect_fail "unreviewed SVG path" - -for rejected_path in \ - "docs/.workspace/private.md" \ - ".github/workflows/internal/private.yml" \ - ".github/workflows/.private.yml" \ - ".cargo/.private.toml" \ - ".devcontainer/.private.json" \ - ".vscode/.private.json"; do - new_case_repository - add_text_file "$rejected_path" - expect_fail "$rejected_path" -done - -new_case_repository -add_text_file "artifact.png" -expect_fail "unreviewed file type" - -new_case_repository -ln -s README.md "$case_repository/linked.md" -git -C "$case_repository" add linked.md -expect_fail "tracked symlink" - -new_case_repository -mkdir -p "$case_repository/.git/info" "$case_repository/docs" -printf 'RESTRICTED-TERM\n' > "$case_repository/.git/info/patterns" -printf 'fixture\n' > "$case_repository/docs/restricted-term.md" -git -C "$case_repository" add docs/restricted-term.md -if ( - cd "$case_repository" - PUBLIC_BOUNDARY_PRIVATE_PATTERNS_FILE="$case_repository/.git/info/patterns" \ - bash scripts/check-public-boundary.sh >/dev/null 2>&1 -); then - echo "public-boundary-test: expected private filename failure" >&2 - exit 1 -fi - -new_case_repository -mkdir -p "$case_repository/.git/info" -printf 'RESTRICTED-TERM\n' > "$case_repository/.git/info/patterns" -printf '\000restricted-term\000' > "$case_repository/evidence.md" -git -C "$case_repository" add evidence.md -if ( - cd "$case_repository" - PUBLIC_BOUNDARY_PRIVATE_PATTERNS_FILE="$case_repository/.git/info/patterns" \ - bash scripts/check-public-boundary.sh >/dev/null 2>&1 -); then - echo "public-boundary-test: expected binary-content failure" >&2 - exit 1 -fi - -new_case_repository -if ( - cd "$case_repository" - env -u PUBLIC_BOUNDARY_PRIVATE_PATTERNS_FILE \ - bash scripts/check-public-boundary.sh >/dev/null 2>&1 -); then - echo "public-boundary-test: expected failure without a private patterns file" >&2 - exit 1 -fi - -new_case_repository -printf '# none\n' > "$case_repository/.git/info/public-boundary-private-patterns" -if ! ( - cd "$case_repository" - env -u PUBLIC_BOUNDARY_PRIVATE_PATTERNS_FILE \ - bash scripts/check-public-boundary.sh >/dev/null -); then - echo "public-boundary-test: expected pass with a default private patterns file" >&2 - exit 1 -fi - -echo "public-boundary-test: passed"