faberun 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +131 -0
- package/bin/faberun.mjs +25 -0
- package/integrations/claude-code/statusline-bench.sh +42 -0
- package/integrations/claude-code/statusline.sh +80 -0
- package/package.json +33 -0
- package/skills/faberun/SKILL.md +24 -0
- package/skills/faberun/references/contract.md +380 -0
- package/skills/faberun/references/engineering.md +29 -0
- package/skills/faberun/references/handoffs.md +26 -0
- package/skills/faberun/references/operations.md +184 -0
- package/skills/faberun/references/rules.md +35 -0
- package/skills/faberun/references/workflow.md +23 -0
- package/skills/init-agentkit/SKILL.md +108 -0
- package/skills/init-agentkit/scripts/install-agentkit.sh +127 -0
- package/skills/init-agentkit/templates/.claude/commands/create-adr.md +44 -0
- package/skills/init-agentkit/templates/.github/workflows/quality.yml +43 -0
- package/skills/init-agentkit/templates/.sentrux/baseline.json +9 -0
- package/skills/init-agentkit/templates/.sentrux/rules.toml +21 -0
- package/skills/init-agentkit/templates/AGENTS.md +110 -0
- package/skills/init-agentkit/templates/docs/ABSTRACTIONS.md +30 -0
- package/skills/init-agentkit/templates/docs/ARCHITECTURE.md +31 -0
- package/skills/init-agentkit/templates/docs/GETTING-STARTED.md +44 -0
- package/skills/init-agentkit/templates/docs/VISION.md +33 -0
- package/skills/init-agentkit/templates/docs/adr/0001-record-architecture-decisions.md +36 -0
- package/skills/init-agentkit/templates/docs/adr/0002-root-managed-ai-guidance.md +37 -0
- package/skills/init-agentkit/templates/docs/adr/0003-sentrux-structural-quality-gates.md +49 -0
- package/skills/init-agentkit/templates/docs/adr/README.md +52 -0
- package/skills/init-agentkit/templates/docs/sentrux.md +66 -0
- package/skills/init-agentkit/templates/githooks/commit-msg +22 -0
- package/skills/init-agentkit/templates/githooks/pre-commit +32 -0
- package/src/campaign/brief.mjs +394 -0
- package/src/campaign/chain.mjs +555 -0
- package/src/campaign/handoff.mjs +516 -0
- package/src/campaign/index.mjs +300 -0
- package/src/campaign/journal.mjs +347 -0
- package/src/campaign/layout.mjs +51 -0
- package/src/campaign/metrics-evals.mjs +25 -0
- package/src/campaign/metrics.mjs +517 -0
- package/src/campaign/projection.mjs +250 -0
- package/src/campaign/record.mjs +102 -0
- package/src/campaign/unpark.mjs +56 -0
- package/src/cli/brand.mjs +205 -0
- package/src/cli/campaign.mjs +730 -0
- package/src/cli/contract.mjs +67 -0
- package/src/cli/init.mjs +170 -0
- package/src/cli/launch.mjs +239 -0
- package/src/cli/seat.mjs +139 -0
- package/src/cli/setup.mjs +294 -0
- package/src/cli/skills.mjs +105 -0
- package/src/cli/update.mjs +216 -0
- package/src/cli.mjs +525 -0
- package/src/contract/articles.mjs +12 -0
- package/src/contract/assert.mjs +162 -0
- package/src/contract/definition-of-done.mjs +97 -0
- package/src/contract/final-verification.mjs +96 -0
- package/src/contract/index.mjs +641 -0
- package/src/contract/judge-envelope.mjs +25 -0
- package/src/contract/review-modes.mjs +151 -0
- package/src/contract/runtime.mjs +204 -0
- package/src/contract/schema-version.mjs +25 -0
- package/src/contract/scope-findings.mjs +77 -0
- package/src/contract/snapshot.mjs +639 -0
- package/src/contract/task-packet.mjs +495 -0
- package/src/contract/untrusted.mjs +75 -0
- package/src/contract/verification.mjs +185 -0
- package/src/contract/worker-result.mjs +138 -0
- package/src/engine/assignment.mjs +63 -0
- package/src/engine/backoff.mjs +492 -0
- package/src/engine/bulk-read.mjs +361 -0
- package/src/engine/cancel.mjs +177 -0
- package/src/engine/detach.mjs +101 -0
- package/src/engine/dispatch.mjs +752 -0
- package/src/engine/failover.mjs +192 -0
- package/src/engine/gate.mjs +183 -0
- package/src/engine/judge-gate.mjs +517 -0
- package/src/engine/lifecycle.mjs +772 -0
- package/src/engine/live-preflight.mjs +299 -0
- package/src/engine/mutation.mjs +146 -0
- package/src/engine/notify-queue.mjs +327 -0
- package/src/engine/process-identity.mjs +72 -0
- package/src/engine/process.mjs +774 -0
- package/src/engine/prompts.mjs +289 -0
- package/src/engine/recover.mjs +300 -0
- package/src/engine/result-file.mjs +222 -0
- package/src/engine/resume.mjs +635 -0
- package/src/engine/retry.mjs +334 -0
- package/src/engine/review.mjs +228 -0
- package/src/engine/run-command.mjs +287 -0
- package/src/engine/run-identity.mjs +411 -0
- package/src/engine/runtime-discovery.mjs +235 -0
- package/src/engine/scheduler.mjs +526 -0
- package/src/engine/scope.mjs +378 -0
- package/src/engine/settle.mjs +207 -0
- package/src/engine/state.mjs +148 -0
- package/src/engine/supervise.mjs +713 -0
- package/src/engine/verify.mjs +167 -0
- package/src/harnesses/agy/index.mjs +62 -0
- package/src/harnesses/catalogue.mjs +509 -0
- package/src/harnesses/claude/index.mjs +90 -0
- package/src/harnesses/codex/index.mjs +87 -0
- package/src/harnesses/dsh/closed-packet.patch.yml +42 -0
- package/src/harnesses/dsh/index.mjs +210 -0
- package/src/harnesses/dsh/runner.mjs +259 -0
- package/src/harnesses/exec-jsonl/index.mjs +788 -0
- package/src/harnesses/index.mjs +508 -0
- package/src/harnesses/protocol.mjs +531 -0
- package/src/harnesses/replay/bin.mjs +386 -0
- package/src/harnesses/replay/index.mjs +238 -0
- package/src/harnesses/zcode/index.mjs +276 -0
- package/src/host/config.mjs +87 -0
- package/src/host/home.mjs +149 -0
- package/src/host/package.mjs +23 -0
- package/src/host/preflight.mjs +520 -0
- package/src/host/tool-policy-decisions.mjs +341 -0
- package/src/host/tool-policy-hook.mjs +270 -0
- package/src/notify/index.mjs +359 -0
- package/src/notify/os-macos.mjs +81 -0
- package/src/repo/declared-paths.mjs +220 -0
- package/src/repo/integrate.mjs +546 -0
- package/src/repo/scope-closure.mjs +665 -0
- package/src/repo/signal-block.mjs +16 -0
- package/src/repo/signal.mjs +222 -0
- package/src/repo/source-identity.mjs +295 -0
- package/src/repo/workspace.mjs +557 -0
- package/src/repo/worktree.mjs +352 -0
- package/src/report/final.mjs +200 -0
- package/src/report/metrics-report.mjs +99 -0
- package/src/report/next.mjs +383 -0
- package/src/report/render.mjs +716 -0
- package/src/run/disk-gc.mjs +251 -0
- package/src/run/lock.mjs +329 -0
- package/src/run/node-store.mjs +62 -0
- package/src/run/operations.mjs +286 -0
- package/src/run/store.mjs +187 -0
- package/src/run/usage.mjs +337 -0
- package/src/seat/harnesses.mjs +83 -0
- package/src/seat/index.mjs +239 -0
- package/src/seat/tmux.mjs +208 -0
- package/src/util.mjs +0 -0
- package/src/web/api.mjs +371 -0
- package/src/web/boundary.mjs +88 -0
- package/src/web/index.html +299 -0
- package/src/web/server.mjs +552 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: ADR
|
|
3
|
+
id: "0001"
|
|
4
|
+
title: "Record architecture decisions"
|
|
5
|
+
status: active
|
|
6
|
+
date: {{DATE}}
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Context
|
|
10
|
+
|
|
11
|
+
As {{PROJECT}} grows with multiple contributors and AI agents, decisions get
|
|
12
|
+
scattered across chat history and commit messages, making it hard to know *why*
|
|
13
|
+
the system looks the way it does.
|
|
14
|
+
|
|
15
|
+
## Decision
|
|
16
|
+
|
|
17
|
+
**Record every structural choice as an Architecture Decision Record in
|
|
18
|
+
`docs/adr/`.** Each decision gets its own numbered, immutable file; a changed
|
|
19
|
+
decision supersedes the prior ADR instead of editing it.
|
|
20
|
+
|
|
21
|
+
## Options considered
|
|
22
|
+
|
|
23
|
+
- **ADR folder with frontmatter** (chosen): versioned alongside the code it
|
|
24
|
+
explains, so a decision and its implementation move together; the frontmatter
|
|
25
|
+
is machine-readable, which lets agents filter by status; the index lives in
|
|
26
|
+
`README.md`.
|
|
27
|
+
- **Only a learnings doc**: lightweight but mixes incidents with irreversible
|
|
28
|
+
architecture choices.
|
|
29
|
+
- **Wiki / external docs**: fine for product, poor for version-controlled
|
|
30
|
+
coupling to code.
|
|
31
|
+
|
|
32
|
+
## Consequences
|
|
33
|
+
|
|
34
|
+
- New structural work adds or supersedes an ADR in the same PR.
|
|
35
|
+
- `docs/ARCHITECTURE.md` summarizes current state; ADRs hold the history.
|
|
36
|
+
- Agents read `docs/adr/` before large refactors (see `AGENTS.md`).
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: ADR
|
|
3
|
+
id: "0002"
|
|
4
|
+
title: "Root-managed AI guidance files"
|
|
5
|
+
status: active
|
|
6
|
+
date: {{DATE}}
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Context
|
|
10
|
+
|
|
11
|
+
Multiple AI tools (Cursor, Claude Code, Gemini CLI) each expect their own
|
|
12
|
+
instruction file at the repository root. Maintaining `CLAUDE.md`, `GEMINI.md`, and
|
|
13
|
+
`CURSOR.md` as separate documents means every guardrail change has to land in each
|
|
14
|
+
of them; in practice one gets updated and the rest drift, so different agents end
|
|
15
|
+
up working under different rules in the same repo.
|
|
16
|
+
|
|
17
|
+
## Decision
|
|
18
|
+
|
|
19
|
+
**`AGENTS.md` at the repo root is the canonical AI + contributor guidance.
|
|
20
|
+
Tool-specific files (`CLAUDE.md`, `GEMINI.md`, `CURSOR.md`, `AGENT.md`)
|
|
21
|
+
are symlinks to `AGENTS.md`.** Update guidance in
|
|
22
|
+
one place only.
|
|
23
|
+
|
|
24
|
+
## Options considered
|
|
25
|
+
|
|
26
|
+
- **AGENTS.md canonical + symlinks** (chosen): one source of truth, and drift is
|
|
27
|
+
impossible by construction rather than by discipline; `AGENTS.md` is the name
|
|
28
|
+
the ecosystem is converging on.
|
|
29
|
+
- **CLAUDE.md only**: works for Claude; other tools miss shared guardrails.
|
|
30
|
+
- **Separate full files per tool**: guaranteed drift.
|
|
31
|
+
|
|
32
|
+
## Consequences
|
|
33
|
+
|
|
34
|
+
- PRs that change workflow, checks, or guardrails edit `AGENTS.md` once.
|
|
35
|
+
- Coding agents prefer links into `docs/` over inflating the root file.
|
|
36
|
+
- A broken symlink on a platform without symlink support falls back to a regen
|
|
37
|
+
step (`init-agentkit --force`).
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: ADR
|
|
3
|
+
id: "0003"
|
|
4
|
+
title: "Sentrux structural quality gates"
|
|
5
|
+
status: active
|
|
6
|
+
date: {{DATE}}
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Context
|
|
10
|
+
|
|
11
|
+
Type checks (`tsc`/equivalent) and tests catch type errors and behavior
|
|
12
|
+
regressions, but they are **blind to structure**: rising coupling, import
|
|
13
|
+
cycles, complexity hotspots, and files quietly turning into god objects. These
|
|
14
|
+
are exactly what makes a small, healthy codebase slow and fragile a year later.
|
|
15
|
+
|
|
16
|
+
[Sentrux](https://github.com/sentrux/sentrux) is a structural-quality sensor that
|
|
17
|
+
scores the dependency/call graph and ratchets against regression. Adopting it now,
|
|
18
|
+
while the repo is small, sets a clean baseline — retrofitting a gate onto an
|
|
19
|
+
already-degraded codebase means either a baseline that locks in the damage or a
|
|
20
|
+
backlog of refactors before the gate can go green.
|
|
21
|
+
|
|
22
|
+
## Decision
|
|
23
|
+
|
|
24
|
+
**Adopt Sentrux as a mandatory structural-quality gate**, in three parts:
|
|
25
|
+
|
|
26
|
+
1. **`.sentrux/rules.toml`** — absolute hard limits (`check`).
|
|
27
|
+
2. **`.sentrux/baseline.json`** — committed reference for regression detection (`gate`).
|
|
28
|
+
3. **CI** — `sentrux check .` on every push/PR; `sentrux gate .` on PRs.
|
|
29
|
+
|
|
30
|
+
The Boy Scout Rule applies: any file a change touches leaves with an
|
|
31
|
+
equal-or-better structural score. Full reference: [../sentrux.md](../sentrux.md).
|
|
32
|
+
|
|
33
|
+
## Options considered
|
|
34
|
+
|
|
35
|
+
- **Sentrux with ratchet** (chosen): quantitative graph-level metrics; ships an
|
|
36
|
+
MCP server so AI agents optimize the same score; complements `tsc`/tests.
|
|
37
|
+
- **Linter complexity rules only**: no project-wide coupling grade, no cycle
|
|
38
|
+
detection, no baseline ratchet.
|
|
39
|
+
- **CodeScene**: richer but a hosted service, heavier than needed early.
|
|
40
|
+
- **Manual review for structure**: does not scale, invisible to agents.
|
|
41
|
+
|
|
42
|
+
## Consequences
|
|
43
|
+
|
|
44
|
+
- Contributors run `sentrux gate --save .` before a refactor and
|
|
45
|
+
`sentrux check . && sentrux gate .` before committing.
|
|
46
|
+
- CI failure on a Sentrux violation blocks merge.
|
|
47
|
+
- Thresholds **only tighten**; loosening requires a superseding ADR. Never add
|
|
48
|
+
ignore rules to pass — fix the structure.
|
|
49
|
+
- The committed baseline moves **up only**.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Architecture Decision Records
|
|
2
|
+
|
|
3
|
+
Architecture Decision Records (ADRs) for **{{PROJECT}}**.
|
|
4
|
+
|
|
5
|
+
## Format
|
|
6
|
+
|
|
7
|
+
Each ADR is markdown with YAML frontmatter:
|
|
8
|
+
|
|
9
|
+
```markdown
|
|
10
|
+
---
|
|
11
|
+
type: ADR
|
|
12
|
+
id: "0001"
|
|
13
|
+
title: "Short decision title"
|
|
14
|
+
status: proposed # proposed | active | superseded | retired
|
|
15
|
+
date: YYYY-MM-DD
|
|
16
|
+
superseded_by: "0007" # only if status: superseded
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Context
|
|
20
|
+
...
|
|
21
|
+
|
|
22
|
+
## Decision
|
|
23
|
+
**What was decided.**
|
|
24
|
+
|
|
25
|
+
## Options considered
|
|
26
|
+
...
|
|
27
|
+
|
|
28
|
+
## Consequences
|
|
29
|
+
...
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Status lifecycle
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
proposed → active → superseded
|
|
36
|
+
↘ retired
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Rules
|
|
40
|
+
|
|
41
|
+
- One decision per file.
|
|
42
|
+
- Files named `NNNN-short-title.md` (monotonic numbering).
|
|
43
|
+
- Once `active`, never edit — supersede instead.
|
|
44
|
+
- [../ARCHITECTURE.md](../ARCHITECTURE.md) reflects active decisions only.
|
|
45
|
+
|
|
46
|
+
## Index
|
|
47
|
+
|
|
48
|
+
| ID | Title | Status |
|
|
49
|
+
|----|-------|--------|
|
|
50
|
+
| [0001](0001-record-architecture-decisions.md) | Record architecture decisions | active |
|
|
51
|
+
| [0002](0002-root-managed-ai-guidance.md) | Root-managed AI guidance files | active |
|
|
52
|
+
| [0003](0003-sentrux-structural-quality-gates.md) | Sentrux structural quality gates | active |
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Sentrux — structural quality gate
|
|
2
|
+
|
|
3
|
+
[Sentrux](https://github.com/sentrux/sentrux) is the structural-quality sensor
|
|
4
|
+
for this repo. It scores the dependency/call graph and **ratchets against
|
|
5
|
+
regression**, complementing (not replacing) type checks and tests.
|
|
6
|
+
|
|
7
|
+
## 1. Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# macOS / Linux — pin the version to match CI (.github/workflows/quality.yml)
|
|
11
|
+
SENTRUX_VERSION={{SENTRUX_VERSION}}
|
|
12
|
+
mkdir -p "$HOME/.sentrux/bin"
|
|
13
|
+
curl -fsSL "https://github.com/sentrux/sentrux/releases/download/${SENTRUX_VERSION}/sentrux-$(uname -s | tr A-Z a-z)-$(uname -m)" \
|
|
14
|
+
-o "$HOME/.sentrux/bin/sentrux" && chmod +x "$HOME/.sentrux/bin/sentrux"
|
|
15
|
+
export PATH="$HOME/.sentrux/bin:$PATH"
|
|
16
|
+
sentrux --version
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## 2. What Sentrux measures
|
|
20
|
+
|
|
21
|
+
- **Coupling grade** (A–F) over the import graph.
|
|
22
|
+
- **Cycles** — import/dependency cycles (target: 0).
|
|
23
|
+
- **God files** — files doing too much.
|
|
24
|
+
- **Complexity** — per-function cyclomatic ceiling.
|
|
25
|
+
- **Quality signal** — an aggregate score to optimize against.
|
|
26
|
+
|
|
27
|
+
## 3. The two commands
|
|
28
|
+
|
|
29
|
+
| Command | Enforces | Config |
|
|
30
|
+
|---------|----------|--------|
|
|
31
|
+
| `sentrux check .` | absolute hard limits | `.sentrux/rules.toml` |
|
|
32
|
+
| `sentrux gate .` | no regression vs baseline | `.sentrux/baseline.json` |
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
sentrux check . # exits 0 if rules pass, 1 if not
|
|
36
|
+
sentrux gate --save . # snapshot baseline (run before a refactor)
|
|
37
|
+
sentrux gate . # compare current vs baseline; fails on degradation
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## 4. Our rules (`.sentrux/rules.toml`)
|
|
41
|
+
|
|
42
|
+
Absolute ceilings. Tighten as the codebase grows — **never loosen without an ADR.**
|
|
43
|
+
|
|
44
|
+
## 5. The baseline (`.sentrux/baseline.json`)
|
|
45
|
+
|
|
46
|
+
Committed reference for `gate`. Move it **up only** — re-saving to mask a
|
|
47
|
+
regression defeats the ratchet.
|
|
48
|
+
|
|
49
|
+
## 6. Daily workflow
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# 1. Before touching existing files, capture where you started:
|
|
53
|
+
sentrux gate --save .
|
|
54
|
+
# 2. Do the work…
|
|
55
|
+
# 3. Before committing:
|
|
56
|
+
sentrux check . && sentrux gate .
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Boy Scout Rule: every file you touch leaves with an equal-or-better score.
|
|
60
|
+
Never silence a rule to pass — fix the structure.
|
|
61
|
+
|
|
62
|
+
## 7. CI integration
|
|
63
|
+
|
|
64
|
+
`.github/workflows/quality.yml` installs the pinned Sentrux release, runs
|
|
65
|
+
`sentrux check .` on every push, and `sentrux gate .` on PRs. A failing gate
|
|
66
|
+
blocks merge.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# {{PROJECT}} commit-msg hook — enforce Conventional Commits.
|
|
3
|
+
# Release tooling parses these; a wrong type breaks versioning. Don't bypass.
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
msg_file="$1"
|
|
7
|
+
subject="$(head -1 "$msg_file")"
|
|
8
|
+
|
|
9
|
+
# allow merge/revert/fixup commits
|
|
10
|
+
case "$subject" in
|
|
11
|
+
"Merge "*|"Revert "*|"fixup! "*|"squash! "*) exit 0 ;;
|
|
12
|
+
esac
|
|
13
|
+
|
|
14
|
+
# type(scope)!: description — scope optional, ! optional
|
|
15
|
+
pattern='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\([a-z0-9_.-]+\))?!?: .+'
|
|
16
|
+
if ! printf '%s' "$subject" | grep -qE "$pattern"; then
|
|
17
|
+
echo "✗ commit-msg: subject does not follow Conventional Commits."
|
|
18
|
+
echo " got: $subject"
|
|
19
|
+
echo " expected: <type>(scope): description (type ∈ feat|fix|docs|refactor|perf|test|build|ci|chore|revert)"
|
|
20
|
+
exit 1
|
|
21
|
+
fi
|
|
22
|
+
exit 0
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# {{PROJECT}} pre-commit hook (installed via core.hooksPath).
|
|
3
|
+
# Never bypass with --no-verify; fix the underlying issue instead.
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
# Skip if nothing staged.
|
|
7
|
+
git diff --cached --quiet && exit 0
|
|
8
|
+
|
|
9
|
+
# --- secrets scan over the staged diff ---------------------------------------
|
|
10
|
+
echo "▸ secrets scan"
|
|
11
|
+
# exclude the hooks themselves (they contain the patterns as literals)
|
|
12
|
+
DIFF="$(git diff --cached -U0 -- . ':(exclude)githooks/**')"
|
|
13
|
+
PATTERNS='(AKIA[0-9A-Z]{16}|xox[baprs]-[0-9A-Za-z-]{10,}|gh[pousr]_[0-9A-Za-z]{20,}|-----BEGIN[ A-Z]*PRIVATE KEY-----|AIza[0-9A-Za-z_-]{30,}|"private_key":)'
|
|
14
|
+
if printf '%s' "$DIFF" | grep -nEi "$PATTERNS" | grep -viE '(example|placeholder|dummy|fake|PATTERNS=)' | head -5 | grep -q .; then
|
|
15
|
+
echo "✗ possible secret in the staged diff — remove it before committing (use a gitignored .env)"; exit 1
|
|
16
|
+
fi
|
|
17
|
+
if git diff --cached --name-only | grep -E '(^|/)\.env($|\.)' | grep -vqE '\.env\.example'; then
|
|
18
|
+
echo "✗ .env file staged — do not commit secrets"; exit 1
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
if [ -f .sentrux/rules.toml ] && command -v sentrux >/dev/null 2>&1; then
|
|
22
|
+
echo "▸ sentrux check"
|
|
23
|
+
sentrux check . || { echo "✗ sentrux check failed — fix structure before committing"; exit 1; }
|
|
24
|
+
if [ -f .sentrux/baseline.json ] && ! grep -q 'placeholder' .sentrux/baseline.json 2>/dev/null; then
|
|
25
|
+
echo "▸ sentrux gate"
|
|
26
|
+
sentrux gate . || { echo "✗ sentrux gate: structural regression on touched files"; exit 1; }
|
|
27
|
+
fi
|
|
28
|
+
elif [ -f .sentrux/rules.toml ]; then
|
|
29
|
+
echo "⚠ sentrux not installed — skipping structural gate (see docs/sentrux.md)"
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
exit 0
|