gabe-assess — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited gabe-assess (Agent Skill) and scored it 45/100 (orange). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 1 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
A base64 string of 128+ characters appears in a documentation file. Encoded prompt injection hides the hostile instruction in base64 — invisible to keyword filters — and relies on the agent's ability to decode it at runtime. There is no normal authoring reason to embed a multi-hundred-byte base64 blob in skill docs.
*.sig, SIGNATURES) outside the documentation.Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Pause before an "obvious yes" and take a photograph of what it actually means. When someone proposes a fix, a change, a detour, or a scope addition that seems straightforward, this skill surfaces what you'd want to know BEFORE agreeing — blast radius, maturity-appropriate scope, prerequisites, and alternatives.
This is NOT a code review (use gabe-roast). This is NOT alignment checking (use gabe-align). This is the moment between "should we do X?" and "yes" — the triage instinct that asks: what am I actually signing up for?
Rendering note. Output templates in this spec wrapped in bare triple-backtick fences are spec-meta delimiters — render their contents as plain markdown at runtime so blast-radius tables display as tables, not monospace code. See gabe-docs/SKILL.md § "Runtime output rendering convention".Use when:
Don't use when:
What someone wants to do or is suggesting you do. Can be:
| Input Type | Example |
|---|---|
| Inline | "Fix the CORS config on staging Storage" |
| Reference | "the two staging issues from the smoke test" |
| Context | "this" or "what you just proposed" |
If the change isn't clear, ask: "What specifically is being proposed?"
The assessment adapts based on what's happening:
If context is ambiguous, state it: "I'm assessing this as a mid-task detour."
What does this change touch?
| Scope | Meaning |
|---|---|
| Contained | Single file, single config, no downstream effects |
| Local | 2-5 files in the same feature/module, tests may need updating |
| Cross-cutting | Multiple modules, shared infrastructure, or affects other projects |
| External | Affects deployed environments, other teams, users, or third-party services |
Is this the right level of fix for where we are?
| Level | What's appropriate |
|---|---|
| MVP | Minimum to unblock. Duct tape is fine. Document the shortcut. |
| Enterprise | Proper fix with tests. No duct tape, but no gold plating either. |
| Scale | Systematic fix. Consider monitoring, rollback, multi-environment. |
The skill identifies which level the CURRENT project/situation is at, and flags when a proposed fix is over-engineered or under-engineered for that level.
What must be true or verified before this change is safe?
Is there a simpler, cheaper, or more appropriate path?
Does this change land in known folder patterns, or does it propose new locations?
Requires .kdbp/STRUCTURE.md. Skip silently if missing.
From the change description, extract the anticipated file paths (explicit paths, inferred new file X.py, or "add Y under Z/"). For each:
| Outcome | Flag |
|---|---|
| Matches an Allowed Pattern at or below project maturity | ✅ in-standard |
| Matches a Disallowed Pattern | ❌ disallowed — explain why |
| No match — new location proposed | ⚠ drift — suggest 2-3 nearest-match allowed patterns, or propose adding this as a new pattern |
A change proposing 3+ files in new locations is a signal — either the STRUCTURE is outdated (project has evolved and needs pattern additions) or the change itself is architecturally questionable. Flag this explicitly in the assessment output.
Output format inside D5:
D5 Structural Fit:
✅ api/routes/incidents.py (matches api/routes/*.py, MVP tier)
⚠ experiments/prompt_eval.py — no matching pattern
Nearest: tests/**/*.py, scripts/**/*.py
Suggest: add `experiments/**/*.py` as Enterprise tier, or reroute to scripts/This catches drift at the cheapest moment — before any code is written. Hook + commit-time CHECK 8 remain as safety nets for changes that skip assess.
Source-of-truth note: STRUCTURE.md Allowed Patterns are the authoritative source for "where files belong" in this project. The Paths column in KNOWLEDGE.md Gravity Wells is a derived view — it maps architectural sections to path globs for activity signals in /gabe-teach brief. When STRUCTURE patterns and wells Paths diverge, STRUCTURE wins. /gabe-teach wells → [paths N] will warn when a user-entered path is absent from STRUCTURE.md Allowed Patterns and suggest adding it there first.
GABE ASSESS: [change description]
Context: [mid-task / planning / post-review / blocker]
D1 BLAST RADIUS: [Contained / Local / Cross-cutting / External]
[1-2 sentences: what specifically is touched and what could ripple]
D2 MATURITY SCOPE: [MVP / Enterprise / Scale]
Current level: [where the project actually is]
Proposed fix level: [what level the fix is scoped at]
[Match / Over-engineered / Under-engineered — and why]
D3 PREREQUISITES:
- [thing to verify or ensure before proceeding]
- [another prerequisite]
(if none: "None identified — change is self-contained")
D4 ALTERNATIVES:
[A] Do nothing — [consequence]
[B] Minimal fix — [what it looks like, effort T-shirt size]
[C] Proper fix — [what it looks like, effort T-shirt size]
[D] Workaround — [if applicable]
D5 STRUCTURAL FIT: (only if .kdbp/STRUCTURE.md exists)
✅ in-standard: [count] ⚠ drift: [count] ❌ disallowed: [count]
[per-file breakdown for drift/disallowed items]
RECOMMENDATION: [A/B/C/D] — [one sentence why]
ONE-LINER: "[memorable handle for this decision — Gabe Lens format]"All dimensions, all alternatives. Use when the change isn't trivial and you need to decide.
brief | bf)ASSESS (brief): [change]
Blast: [scope] | Maturity: [match/over/under] | Prereqs: [count]
Rec: [A/B/C/D] — [one line]
Handle: "[one-liner]"Use when you want a quick gut-check, not a full analysis. Good for triaging multiple changes in sequence.
inline | il)A single sentence inserted into conversation flow, no formatting:
"Before we fix CORS: that's an External-scope change touching GCP bucket config shared with Gustify — verify Gustify isn't using the same bucket first. Minimal fix is a 1-line gsutil command."
Use when the assessment should feel like a colleague's aside, not a document.
When multiple changes are proposed together (e.g., "fix these two staging issues"):
ASSESS (batch): [group description]
| # | Change | Blast | Maturity | Rec |
|---|--------|-------|----------|-----|
| 1 | [desc] | [scope] | [match] | [A/B/C/D] |
| 2 | [desc] | [scope] | [match] | [A/B/C/D] |
Combined: [independent / coupled / sequenced]
Order: [which first, if it matters]
Handle: "[one-liner for the batch decision]"/gabe-assess on each gap's suggested fix before implementing./gabe-align shallow first, then /gabe-assess on the aligned approach./gabe-lens on the underlying concept.GABE ASSESS: Fix Storage CORS and Firestore permissions for staging scan testing
Context: blocker — fixture pipeline is deployed but can't be verified due to staging infra gaps
D1 BLAST RADIUS: External
CORS: touches GCP bucket config for boletapp-staging.firebasestorage.app.
This bucket is shared with Gustify. CORS changes affect all apps using this bucket.
Firestore: staging rules file is shared between Boletapp and Gustify (documented in INC-001).
Deploying rules from Boletapp could overwrite Gustify's staging rules.
D2 MATURITY SCOPE: MVP
Current level: MVP (solo dev, staging env for testing)
Proposed fix level: MVP-appropriate (config changes, not code)
Match — but the SHARED infrastructure elevates the blast radius beyond what
a solo MVP fix normally implies.
D3 PREREQUISITES:
- Verify Gustify doesn't have its own CORS config on the same bucket
- Check if staging rules are deployed from Gustify or Boletapp repo (INC-001 says Gustify)
- Confirm Alice's UID is in the allowedEmails whitelist on staging
D4 ALTERNATIVES:
[A] Do nothing — Fixture system works server-side (unit tests prove it).
E2E verification deferred until staging infra is fixed separately.
[B] Minimal fix — Set CORS on bucket + add Alice to allowedEmails. No rules deploy. (S)
[C] Proper fix — CORS + rules deploy from Gustify repo with combined rules. (M)
[D] Workaround — Test via admin script (bypass client, call CF directly). (S)
RECOMMENDATION: [B] — CORS is a bucket-level setting (doesn't affect rules),
and allowedEmails is a Firestore doc addition (doesn't require rules deploy).
Neither touches the shared rules file.
ONE-LINER: "Bucket knob and guest list — don't redecorate the shared house"~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.