Skip to content
This repository was archived by the owner on Jul 9, 2026. It is now read-only.
Closed
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
7 changes: 7 additions & 0 deletions .github/workflows/standard-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ jobs:
jq . .claims/claims.json >/dev/null
fi

- name: Verify Managed Rules
run: |
chmod +x scripts/verify-managed-rules.sh || true
if [ -f scripts/verify-managed-rules.sh ]; then
./scripts/verify-managed-rules.sh
fi

- name: Run tests
run: |
chmod +x scripts/test.sh || true
Expand Down
54 changes: 54 additions & 0 deletions .github/workflows/version-bump.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Version Bump

on:
workflow_dispatch:
inputs:
stage:
description: "Target stage"
required: true
type: choice
options:
- dev
- qa
- beta
- prod
bump:
description: "Semver bump type"
required: true
type: choice
options:
- patch
- minor
- major

jobs:
bump:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "20"

- name: Bump version
run: |
chmod +x scripts/version.sh
scripts/version.sh "${{ inputs.stage }}" "${{ inputs.bump }}"

- name: Commit changes
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
if [[ -n "$(git status --porcelain)" ]]; then
VERSION="$(cat .version)"
git add .version package.json VERSIONING.md scripts/version.sh || true
git commit -m "chore(version): bump to ${VERSION} [${{ inputs.stage }}]"
git push
else
echo "No version changes to commit"
fi
1 change: 1 addition & 0 deletions .managed-rules-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v1.1.0
1 change: 1 addition & 0 deletions .version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.1.0-dev.1
26 changes: 9 additions & 17 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
# Agent Execution Rules

Any model or coding agent using this repository should start here.

Primary source of truth:

- `docs/shared-coding-rules.md`

Model-specific entry files:

- `CODEX.md`
- `CLAUDE.md`
- `GEMINI.md`

Rule:

If a task changes product behavior, backend or frontend flow, contracts, policies, or deployment behavior, read `docs/shared-coding-rules.md` before editing code.
# Agent Git Rules

- Run `git status -sb` before work.
- Sync base first: `git checkout main && git pull --ff-only origin main`.
- Create feature branch per task.
- No force-push on shared branches.
- Do not commit secrets (`.env`, tokens, logs).
- Open PR for merge to `main`.
- Follow managed [RULEBOOK.md](./RULEBOOK.md) before adding APIs or shared logic.
26 changes: 26 additions & 0 deletions COST-TRACKING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Cost Tracking

## Purpose
This repository must track usage and cost events in an append-only model so billing and analytics are reproducible.

## Minimum Requirements
1. Every billable event must include a unique idempotency key (`event_id`).
2. Metering writes must be append-only and immutable.
3. Usage rows must capture:
- product
- feature
- customer_id
- usage_count
- cost_unit
- total_cost
- billing_period
- source_event_id
4. Rollups must be deterministic and replayable from raw metering rows.
5. Duplicate source events must be ignored via a unique constraint on `source_event_id`.

## Validation Checklist
- [ ] API ingests metering with `usage_count` and calculates `total_cost = usage_count * cost_unit`.
- [ ] Database enforces unique `source_event_id`.
- [ ] Rollup job aggregates from raw usage rows, not from ad hoc counters.
- [ ] Admin endpoint exists to trigger rollup/invoice generation manually.
- [ ] Test coverage includes duplicate-event idempotency.
48 changes: 48 additions & 0 deletions RULEBOOK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Engineering Rulebook

Rulebook version: `v1.1.0`
Managed by: `dev-bootstrap`

## Mandatory Rules

1. Do not create duplicate APIs.
2. Do not create duplicate business logic in multiple files/services without explicit approval.
3. Reuse existing modules before adding new ones.
4. Every new endpoint must be preceded by a duplication check.
5. Every new shared utility must be preceded by a duplication check.

## Duplicate API Prevention Standard

Before adding an endpoint:

1. Search existing routes:
```bash
rg -n "app\\.(get|post|put|patch|delete)|router\\.(get|post|put|patch|delete)|route\\(" src
```
2. Search API docs/spec:
```bash
rg -n "GET |POST |PUT |PATCH |DELETE " API.md docs
```
3. If an endpoint exists with overlapping purpose, extend it instead of creating a sibling API.
4. If a new endpoint is required, document why existing APIs cannot be extended.

## Duplicate Code Prevention Standard

Before adding new logic:

1. Search for similar names/behavior:
```bash
rg -n "<keyword>|<function_name>|<domain_term>" src
```
2. Prefer extracting shared logic into one reusable module.
3. If intentional duplication is unavoidable (e.g., hard boundary constraints), add a short justification comment and link issue/ADR.

## PR Checklist (Required)

- [ ] I searched for existing API endpoints and confirmed no duplicate contract is introduced.
- [ ] I searched for existing logic and reused/extended it where possible.
- [ ] If duplication remains, I documented explicit justification.

## Sync Policy

`RULEBOOK.md` is a managed file and may be overwritten by org sync tooling.
24 changes: 24 additions & 0 deletions VERSIONING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Versioning Standard

## Goal
Use one environment-aware version format across dev, QA, beta, and production.

## Format
- `dev`: `X.Y.Z-dev.N`
- `qa`: `X.Y.Z-qa.N`
- `beta`: `X.Y.Z-beta.N`
- `prod`: `X.Y.Z`

## Commands
```bash
scripts/version.sh dev patch
scripts/version.sh qa patch
scripts/version.sh beta minor
scripts/version.sh prod patch
```

## Rules
1. Always bump before deploy.
2. `prod` versions must not include prerelease suffixes.
3. The canonical value is stored in `.version`.
4. If `package.json` exists, its `version` must match `.version`.
30 changes: 30 additions & 0 deletions scripts/verify-managed-rules.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env bash
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
RULEBOOK="$ROOT_DIR/RULEBOOK.md"
AGENTS="$ROOT_DIR/AGENTS.md"
VERSION_FILE="$ROOT_DIR/.managed-rules-version"

fail() {
echo "[verify-managed-rules][error] $*" >&2
exit 1
}

[[ -f "$RULEBOOK" ]] || fail "Missing RULEBOOK.md"
[[ -f "$AGENTS" ]] || fail "Missing AGENTS.md"
[[ -f "$VERSION_FILE" ]] || fail "Missing .managed-rules-version"

EXPECTED_VERSION="$(cat "$VERSION_FILE" | tr -d '[:space:]')"
[[ -n "$EXPECTED_VERSION" ]] || fail "Empty .managed-rules-version"

grep -q "Rulebook version: \`$EXPECTED_VERSION\`" "$RULEBOOK" || \
fail "RULEBOOK.md version mismatch. Expected $EXPECTED_VERSION"

grep -q "Managed by: \`dev-bootstrap\`" "$RULEBOOK" || \
fail "RULEBOOK.md is not marked as managed by dev-bootstrap"

grep -q "Follow managed \[RULEBOOK.md\]" "$AGENTS" || \
fail "AGENTS.md missing required managed rulebook reference"

echo "[verify-managed-rules] OK ($EXPECTED_VERSION)"
90 changes: 90 additions & 0 deletions scripts/version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/usr/bin/env bash
set -euo pipefail

# Environment-aware semantic versioning helper.
# Stages:
# - dev => X.Y.Z-dev.N
# - qa => X.Y.Z-qa.N
# - beta => X.Y.Z-beta.N
# - prod => X.Y.Z

STAGE="${1:-}"
BUMP="${2:-patch}"
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
VERSION_FILE="$ROOT_DIR/.version"
PACKAGE_JSON="$ROOT_DIR/package.json"

usage() {
cat <<USAGE
Usage: scripts/version.sh <dev|qa|beta|prod> [patch|minor|major]
USAGE
}

if [[ -z "$STAGE" ]]; then
usage
exit 1
fi

if [[ "$STAGE" != "dev" && "$STAGE" != "qa" && "$STAGE" != "beta" && "$STAGE" != "prod" ]]; then
echo "Invalid stage: $STAGE" >&2
usage
exit 1
fi

if [[ "$BUMP" != "patch" && "$BUMP" != "minor" && "$BUMP" != "major" ]]; then
echo "Invalid bump: $BUMP" >&2
usage
exit 1
fi

read_version() {
if [[ -f "$VERSION_FILE" ]]; then
cat "$VERSION_FILE"
return
fi
if [[ -f "$PACKAGE_JSON" ]]; then
node -e "console.log(require('$PACKAGE_JSON').version || '0.1.0-dev.1')"
return
fi
echo "0.1.0-dev.1"
}

CURRENT="$(read_version)"
BASE="$(echo "$CURRENT" | sed -E 's/-.*$//')"
MAJOR="$(echo "$BASE" | cut -d. -f1)"
MINOR="$(echo "$BASE" | cut -d. -f2)"
PATCH="$(echo "$BASE" | cut -d. -f3)"

case "$BUMP" in
major)
MAJOR=$((MAJOR + 1)); MINOR=0; PATCH=0 ;;
minor)
MINOR=$((MINOR + 1)); PATCH=0 ;;
patch)
PATCH=$((PATCH + 1)) ;;
esac

NEXT_BASE="${MAJOR}.${MINOR}.${PATCH}"
NEXT_VERSION="$NEXT_BASE"

if [[ "$STAGE" != "prod" ]]; then
PREV_STAGE=""
PREV_N=0
if echo "$CURRENT" | grep -Eq -- '-(dev|qa|beta)\.[0-9]+$'; then
PREV_STAGE="$(echo "$CURRENT" | sed -E 's/^.*-(dev|qa|beta)\.[0-9]+$/\1/')"
PREV_N="$(echo "$CURRENT" | sed -E 's/^.*-(dev|qa|beta)\.([0-9]+)$/\2/')"
fi
if [[ "$PREV_STAGE" == "$STAGE" ]]; then
NEXT_VERSION="${NEXT_BASE}-${STAGE}.$((PREV_N + 1))"
else
NEXT_VERSION="${NEXT_BASE}-${STAGE}.1"
fi
fi

echo "$NEXT_VERSION" > "$VERSION_FILE"

if [[ -f "$PACKAGE_JSON" ]]; then
node -e "const fs=require('fs');const p='$PACKAGE_JSON';const j=JSON.parse(fs.readFileSync(p,'utf8'));j.version='$NEXT_VERSION';fs.writeFileSync(p, JSON.stringify(j,null,2)+'\n');"
fi

echo "Updated version: $CURRENT -> $NEXT_VERSION"
Loading