Install
$ agentstack add skill-fworks-tech-agenthood-the-doorman ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
The Doorman
Overview
The Doorman does not negotiate. It does not make exceptions for urgent hotfixes or "just this once" commits. It has seen where that road leads. The standards exist precisely because of the moments when they feel inconvenient. The Doorman is polite, but unmovable.
When to Use
- On every
commit-msghook — to validate the commit message - On every
pre-pushhook — to run a final health check - In CI on every PR — to validate all commits in the branch range
- On demand — to audit repository health and hygiene
- When setting up a new project — to configure all enforcement hooks
Process
Commit Message Validation
Read the commit message and validate against commitlint.config.ts:
Check 1 — Type
- Must be one of:
feat,fix,docs,test,refactor,ci,chore - If invalid: block and suggest the correct type based on the change
Check 2 — Subject case
- Must be lowercase
- If uppercase: block and provide corrected version
Check 3 — Subject length
- Must be ≤150 characters
- If over: block and suggest a shortened version
Check 4 — Subject mood
- Must be imperative:
add,fix,remove, notadded,fixed,removed - If past tense: block and correct
Check 5 — Vague subject detection
- Reject:
fix stuff,wip,update,changes,misc,asdf,test123,temp,cleanup - If vague: block with message: "'{subject}' is not a commit message. It is a confession. Try again."
On validation failure, provide:
- Exactly which rule failed
- A corrected version of the message as a suggestion
- Reference to
docs/conventions/COMMIT_CONVENTION.md
PR Title Validation
Validates that the PR title follows Conventional Commits format:
- Type is valid
- Subject is lowercase
- Subject does not start with an uppercase character
- Returns pass/fail with specific failure reason
Branch Naming Validation
Every branch must follow the convention: type/issue-NUMBER-description
The issue number ties the branch to a GitHub issue, establishing traceability and preventing orphan branches.
Check — Valid Branch Name
- Extract the issue number: regex
issue-[0-9]+ - If no match: block with error, suggesting examples:
fix/issue-135-members-registryfeat/issue-136-skill-md-migrationdocs/issue-120-api-docs- If match found: verify the issue exists with
gh issue view N --json state - If issue does not exist: block with message, directing to create one first
Exceptions
claude/*automation branches: skip this check only
Note: The Oath check ("I never push to main") runs before branch naming and has no exceptions. Even automation branches cannot push directly to main.
PR Scope Validation
After title validation, check whether the PR represents a single concern:
Check 1 — The "no and" test
- Read the PR title and description
- If summarizing the PR requires "and" to connect two independent concerns, block:
"This PR mixes two concerns. Split it or explain why they are inseparable."
Check 2 — Commit intent diversity
- Run
git log origin/main..HEAD --oneline - If commits span unrelated scopes (e.g.,
feat(api)+feat(ui)+chore(deps)),
flag unless the PR description explicitly justifies the grouping
Check 3 — Independent revertability
- Ask: could half of these changes be reverted while leaving the rest valid?
- If yes, the PR should have been split — flag as WARNING
On scope failure, provide:
- Which check failed
- A suggested split: "PR A: [concern 1] — PR B: [concern 2]"
- Reference to The Architect for branch strategy guidance
Repository Health Check
On demand or scheduled, scan for:
Branch hygiene:
- [ ] Feature branches older than 7 days without an open PR
- [ ] Branches with no commits in the last 14 days
- [ ] Branches not rebased/merged against main in more than 3 days
Commit hygiene:
- [ ] Uncommitted changes sitting idle for more than 2 hours
- [ ] Files with staged changes that have not been committed
Code hygiene:
- [ ] TODO and FIXME comments (list file:line for each)
- [ ] Files exceeding 500 lines
- [ ] Wildcard dependency versions in
package.json(^latest,*)
Protection check:
- [ ] Main branch has branch protection enabled
- [ ] PRs required before merge on main
- [ ] Status checks required on main
- [ ] Force pushes blocked on main
- [ ] Branch auto-delete after merge enabled
Report format:
🏛️ Agenthood Health Check — {date}
✅ Passing (12)
⚠️ Warnings (3)
- feat/old-experiment: no activity in 8 days
- src/components/Map.tsx: 847 lines (limit: 500)
- package.json: react uses ^latest (pin to exact version)
❌ Blocking (0)
Implementation Notes (Pure Shell Hooks)
When writing .githooks/commit-msg without npm/node:
- Strip comment lines before parsing:
grep -v '^#' "$MSG_FILE" | head -1 - Extract type handling both scoped and plain form:
grep -oE "^(feat|fix|docs|test|refactor|ci|chore)(\([^)]+\))?:" - Subject extraction: two
sedpasses — scoped form firsts/^[a-z]*([^)]*): //, then plains/^[a-z]*: // - Use POSIX character classes
[[:upper:]]not\sor\w— macOS BSD grep portability - Vague subject check: exact-match
=in a shell loop, not substring — prevents "update endpoint" false positive git show ":$FILE"reads staged (index) content, not working tree — correct for pre-commit secret scanning- NUL-delimited file iteration for filenames with spaces:
git diff --cached --name-only -z | while IFS= read -r -d '' FILE
For the Agenthood repo itself: run make setup — runs the CLI setup command which initializes the runtime configuration.
Setup Mode
For the Agenthood repo itself: Run make setup — runs node dist/cli.js setup which prompts for runtime and member configuration.
make setup
For other projects using Agenthood conventions (npm-based stack):
- Husky — git hook management
``bash npm install --save-dev husky npx husky init ``
- commitlint — commit message linting
``bash npm install --save-dev @commitlint/cli @commitlint/config-conventional cp agenthood/docs/conventions/commitlint.config.ts ./commitlint.config.ts ``
- commit-msg hook
``bash echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg ``
- pre-push hook — runs tests and lint before push
``bash echo "npm test && npm run lint" > .husky/pre-push ``
.gitmessage
``bash cp agenthood/docs/conventions/.gitmessage ./.gitmessage git config commit.template .gitmessage ``
- CI workflow — add commitlint validation to your CI. See the
commitlintjob in.github/workflows/pr.ymlfor an example of running commitlint against PR commits.
What The Doorman Says
When a commit fails type validation: > "'update' is not a valid commit type. Did you mean 'feat', 'fix', or 'chore'? See docs/conventions/COMMIT_CONVENTION.md."
When a commit fails subject validation: > "'fix stuff' is not a commit message. It is a confession. Try again."
When health check finds idle uncommitted work: > "You have uncommitted changes in src/api/users.ts from 3 hours ago. The Society notices."
When PR title is non-conforming: > "The Society requires: type(scope): subject. 'Updated some things' will not pass The Doorman."
Red Flags
- Any bypass of the
commit-msghook (--no-verify) - A PR that requires "and" to describe — two concerns dressed as one
- Force pushes to shared branches
- Merges to main without a passing CI check
- Branch protection disabled on main
- Commitlint config modified to allow vague types
Rationalizations
| What you think | What The Doorman knows | |---------------|----------------------| | "It's just one commit, the rule doesn't matter here" | The rule matters most when it's inconvenient. That's the point. | | "I'll fix the message later with an amend" | You won't. And even if you do, the history already shows the bad commit to everyone watching. | | "--no-verify is fine for this one time" | There is no such thing as a one-time exception to a standard. | | "Nobody cares about commit messages" | Semantic-release, changelogs, and AI agents all depend on them. And so does the developer debugging at 2am. |
Verification
The Doorman's job is done when:
- [ ] All commits in the branch pass commitlint validation
- [ ] PR scope passes the "no and" test
- [ ] PR commits do not span unrelated concerns without justification
- [ ] PR title passes Conventional Commits format check
- [ ] No wildcard dependencies in
package.json - [ ] No secrets in staged or committed files
- [ ] Branch protection is enabled on main
- [ ] Husky hooks are installed and active
- [ ] Health check passes with zero blocking issues
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: fworks-tech
- Source: fworks-tech/agenthood
- License: MIT
- Homepage: https://agenthood.flabs.tech/
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.