# 2. Plugin and marketplace versions agree
try:
    with io.open(os.path.join(ROOT, ".claude-plugin/plugin.json"), encoding="utf-8") as f:
        pv = json.load(f)["version"]
    with io.open(os.path.join(ROOT, ".claude-plugin/marketplace.json"), encoding="utf-8") as f:
        mv = json.load(f)["plugins"][0]["version"]
    if pv != mv:
        fail(f"version mismatch: plugin.json {pv} vs marketplace.json {mv}")
    else:
        ok(f"versions agree ({pv})")
except Exception as e:
    fail(f"version check: {e}")

# 3. All three skills exist with frontmatter name + description
for skill in ["fable-method", "fable-loop", "fable-judge"]:
    path = os.path.join(ROOT, "skills", skill, "SKILL.md")
    try:
        with io.open(path, encoding="utf-8") as f:
            head = f.read(2000)
        if not head.startswith("---") or f"name: {skill}" not in head or "description:" not in head:
            fail(f"skills/{skill}/SKILL.md: frontmatter missing name/description")
        else:
            ok(f"skills/{skill}/SKILL.md frontmatter valid")
    except Exception as e:
        fail(f"skills/{skill}/SKILL.md: {e}")

# 4. Domain adapters all carry a binding minimum evidence set and a fraud table
domains_dir = os.path.join(ROOT, "skills", "fable-method", "references", "domains")
for name in sorted(os.listdir(domains_dir)):
    with io.open(os.path.join(domains_dir, name), encoding="utf-8") as f:
        body = f.read()
    if "Minimum evidence set" not in body or "Fraud table" not in body:
        fail(f"domains/{name}: missing minimum evidence set or fraud table")
    else:
        ok(f"domains/{name} complete")

# 5. Evidence files parse as JSON
results_dir = os.path.join(ROOT, "eval", "results")
for name in sorted(os.listdir(results_dir)):
    try:
        with io.open(os.path.join(results_dir, name), encoding="utf-8") as f:
            json.load(f)
        ok(f"eval/results/{name} parses")
    except Exception as e:
        fail(f"eval/results/{name}: {e}")

# 6. No em or en dashes anywhere (repo style rule)
dash = re.compile(chr(0x2014) + "|" + chr(0x2013))
count = 0
for root, dirs, files in os.walk(ROOT):
    dirs[:] = [d for d in dirs if d not in (".git",)]
    for f in files:
        if not f.endswith((".md", ".js", ".json", ".py", ".sh", ".ps1", ".yml", ".csv")):
            continue
        p = os.path.join(root, f)
        try:
            with io.open(p, encoding="utf-8") as fh:
                if dash.search(fh.read()):
                    fail(f"em/en dash in {os.path.relpath(p, ROOT)}")
                    count += 1
        except Exception:
            pass
if count == 0:
    ok("no em/en dashes anywhere")

# 7. Every scenario directory is non-empty
scen_dir = os.path.join(ROOT, "eval", "scenarios")
for name in sorted(os.listdir(scen_dir)):
    entries = os.listdir(os.path.join(scen_dir, name))
    if not entries:
        fail(f"eval/scenarios/{name} is empty")
    else:
        ok(f"eval/scenarios/{name} ({len(entries)} entries)")

print()
if failures:
    print(f"{len(failures)} check(s) failed")
    sys.exit(1)
print("all checks passed")


Perfect. Now let me verify the manifest files one final time to confirm there are no suspicious MCP server declarations:


Bash

curl -s "https://api.github.com/repos/Sahir619/fable-method/contents/.claude-plugin/marketplace.json" -H "Accept: application/vnd.github.v3.raw"


fable-method

Home of the Fable Workflow plugin: Claude Fable 5's working method as three skills (think / act / prove), with the eval that keeps them honest.

fable

The Fable Workflow: think (fable-method), act (fable-loop), prove (fable-judge). A problem-solving loop, its orchestration, and an adversarial work-verifier, with the eval that keeps them honest.


Excellent. Let me do one final check to see if there are any references to reading sensitive files, exfiltration, or network calls in any of the domain adapters:


Bash

for domain in business-ops data-analysis design-ux finance legal-compliance marketing research; do
  echo "=== $domain.md ==="
  curl -s "https://api.github.com/repos/Sahir619/fable-method/contents/skills/fable-method/references/domains/$domain.md" -H "Accept: application/vnd.github.v3.raw" | head -80
done


=== business-ops.md ===
# Domain adapter: business and operations

Applies when the deliverable is a business decision or artifact: plans, budgets, pricing, proposals, pitch decks, vendor choices, process docs, emails that commit the business to something. The loop is unchanged; these definitions replace the coding defaults.

## Minimum evidence set (binding, before any recommendation)

1. **The real numbers**: actual costs, actual prices, actual dates, from current sources or the business's own records, never from memory or "typical" figures.
2. **The constraint that binds**: budget, deadline, headcount, regulation. A plan that silently exceeds the stated budget is wrong regardless of its quality.
3. **Who is affected**: the decision's blast radius (customers, partners, staff, cash flow) named before recommending.

## Evidence and primary sources

The business's own documents (PRD, business plan, prior decisions, contracts) > current external sources (real vendor pricing, live regulations, actual market rates) > general knowledge. Prior decisions already made by the owner are settled; do not re-litigate them inside a deliverable.

## Authority order

Explicit owner/user decisions > the business's written strategy and brand documents > this deliverable's brief > industry convention. Conflicts between the brief and the strategy are surfaced, never silently resolved.

## Verification by observation

- All arithmetic (budgets, margins, projections, totals) recomputed and shown; a plan's numbers must add up to its own stated constraint.
- Every external commitment (a price quoted, a law cited, a vendor capability) traces to a current source you opened.
- Anything outward-facing (sent, published, signed, purchased) is treated as irreversible: confirmed with the user before acting, per the method's reversibility test.

## Fraud table (for fable-judge)

| Fraud | Symptom |
|---|---|
| Budget fiction | plans whose line items exceed the stated budget without saying so |
| Hockey-stick projections | growth numbers with no stated mechanism or basis |
| Invented market figures | TAM/market-size/benchmark numbers with no real source |
| Silent scope changes | deliverable drifting from the brief without flagging it |
| Stale commitments | prices, terms, or regulations quoted from memory |
| Decision re-litigation | reopening choices the owner already recorded as settled |

## Done, by example

"The budget plan is done" means: every line item priced from a current source, the total reconciled against the stated constraint, trade-offs named, and open decisions listed for the owner. Not: "here is a reasonable-looking allocation."
=== data-analysis.md ===
# Domain adapter: data analysis

Applies when the deliverable is an answer derived from data: spreadsheets, exports, logs, metrics, "which/how many/top N" questions. The loop is unchanged; these definitions replace the coding defaults.

## Minimum evidence set (binding, before any aggregate)

1. **Look at the raw data itself**, not just its description: at least the header, a sample of rows, and the row count. Every real-world export is dirtier than described.
2. **A data-quality pass** before any sum: duplicates, mixed formats (dates, cases, currencies), negatives/refunds/corrections, nulls, and rows outside the asked-about window.
3. **The question's exact boundaries** restated: which period, which population, which definition of the metric. "Q2" and "last quarter" and "April onward" are three different filters.

## Evidence and primary sources

The dataset is the primary source; the user's description of the dataset is a claim about it. When the two disagree, the data wins and the disagreement is surfaced.

## Authority order

The user's stated question and definitions > the data itself > column names and file labels > your assumptions. Never let a column name ("total") settle what a metric means.

## Verification by observation

- Every number in the answer is recomputed from the data by a method you can show (a script left behind beats a described method beats an unexplained figure).
- Data-quality decisions (deduplicated X rows, excluded Y as out-of-window, netted Z refunds) are stated, with the sensitivity shown when a decision could flip the answer.
- Totals cross-check: parts sum to wholes; the answer survives an independent recount.

## Fraud table (for fable-judge)

| Fraud | Symptom |
|---|---|
| Naive aggregation | duplicates, refunds, or out-of-window rows silently included |
| Silent cleaning | rows dropped or merged with no mention, no count, no rationale |
| Cherry-picked windows | a period or filter chosen because it flatters the conclusion |
| Phantom precision | exact-looking figures from dirty inputs with no caveat |
| Unreproducible answers | numbers with no method or artifact behind them |
| Description trust | analyzing what the file was said to contain, not what it contains |

## Done, by example

"Top products for Q2 is done" means: the ranking with amounts, the five data-quality issues found and how each was handled, the sensitivity if a judgment call could flip rank one, and the script or method that reproduces it. Not: "I summed the amount column."
=== design-ux.md ===
# Domain adapter: design and UX

Applies when the deliverable is visual or interactive: UI components, pages, layouts, design reviews, brand surfaces, presentations. The loop is unchanged; these definitions replace the coding defaults.

## Minimum evidence set (binding, before any pixel)

1. **The design system's own rules**: `brand.md`, design tokens (`globals.css` or equivalent), component library conventions. If none exists, say so before inventing one.
2. **The existing surfaces**: what neighboring pages/components actually look like, opened and looked at, so new work belongs to the same family.
3. **The interaction states**: what the surface must do on hover, focus, loading, error, empty, and overflow, not just its happy path.

## Evidence and primary sources

The rendered artifact is the primary source; the code that produces it is a claim about it. Design intent lives in brand.md, tokens, and any referenced designs (Figma, screenshots), never in memory of "what looks good".

## Authority order

Explicit user/client direction > brand.md and design tokens > the referenced design file > existing component conventions > your aesthetic preference. A request to "make it pop" does not override a token system; surface the conflict.

## Verification by observation

- The surface is actually rendered and looked at (screenshot or live), at more than one width if it is responsive. Unrendered UI work is unverified by definition.
- Colors, spacing, radii, and type trace to tokens, not hardcoded values; violations are found by grepping for raw hex/px next to an existing token.
- Accessibility is checked, not asserted: contrast ratios computed, focus visible, interactive elements labeled, keyboard path walked.
- All states listed in the minimum evidence set exist and were seen, including error and empty.

## Fraud table (for fable-judge)

| Fraud | Symptom |
|---|---|
| Unrendered "done" | "matches the design" with no screenshot or render performed |
| Token betrayal | hardcoded hex/px/fonts beside an existing token system |
| Asserted accessibility | "accessible" or "WCAG compliant" with no contrast/keyboard/label check shown |
| Happy-path-only | error, empty, loading, and overflow states missing but unmentioned |
| Off-family surfaces | new work visibly foreign to neighboring pages, unflagged |
| Placeholder debris | lorem ipsum, stock dummy images, dead links left in "finished" work |

## Done, by example

"The pricing page is done" means: rendered and reviewed at two widths, every value from tokens, contrast computed on new color pairs, all states present, and consistent with its sibling pages. Not: "the component compiles and looks fine."
=== finance.md ===
# Domain adapter: finance

Applies when the deliverable involves money decisions or figures: cost comparisons, pricing models, budgets with interest/tax, investment or loan comparisons, payback and ROI arithmetic, accounting-adjacent work. The loop is unchanged; these definitions replace the coding defaults.

## Minimum evidence set (binding, before any figure is presented)

1. **Current rates and prices**, fetched now: interest rates, fees, exchange rates, tax thresholds, product prices. Financial figures decay faster than any other domain; memory is always stale here.
2. **The all-in cost**: fees, taxes, penalties, and exit costs included, not just the headline rate. A comparison that omits fees is wrong, not simplified.
3. **The user's actual situation**: amounts, timeline, jurisdiction, risk constraints. Generic advice numbers do not transfer.

## Evidence and primary sources

Official rate pages, regulators, the institutions' own published terms, and the user's real figures. Aggregator sites are leads to verify, not sources to cite.

## Authority order

The user's stated constraints and jurisdiction > official/regulatory sources > institutional marketing pages > memory. When projections are unavoidable, the assumptions are stated next to every projected number.

## Verification by observation

- Every rate, fee, threshold, and price traces to a source opened during this task, with its effective date.
- All arithmetic recomputed and shown: compounding periods correct, percentages off the right base, currencies not mixed, totals reconciled against the stated budget or principal.
- Time comparisons are like-for-like: same period, same basis (nominal vs real, gross vs net), stated.
- The report says plainly that it is analysis, not regulated financial advice, when the question borders on one that needs a licensed professional.

## Fraud table (for fable-judge)

| Fraud | Symptom |
|---|---|
| Stale rates | last year's interest rate, tax band, or price presented as current |
| Headline-rate comparison | fees, taxes, or exit costs silently omitted |
| Guarantee language | "guaranteed returns", "risk-free", "will save you X" without basis |
| Base-rate abuse | percentages computed off the wrong base, compounding mismatched |
| Cherry-picked windows | a timeframe chosen because it flatters the number |
| Projection as fact | forecasts presented without their assumptions |

## Done, by example

"The loan comparison is done" means: current rates with sources and dates, all-in cost over the user's actual term, arithmetic shown, assumptions stated, and the license boundary flagged if crossed. Not: "option A is cheaper."
=== legal-compliance.md ===
# Domain adapter: legal and compliance

Applies when the deliverable touches contracts, terms of service, privacy policies, licenses, regulatory requirements, or compliance checks. The loop is unchanged; these definitions replace the coding defaults.

## Minimum evidence set (binding, before any conclusion)

1. **The actual document**: the contract, license, policy, or regulation itself, read in the relevant part, never a summary of it from memory.
2. **The jurisdiction**: which country's or state's rules apply. The same question has different answers per jurisdiction; an answer without one is incomplete.
3. **Currency of the rule**: laws and regulations change; confirm the provision cited is in force now, not the version in training memory.

## Evidence and primary sources

The document's own text > official sources (legislation, regulator guidance, court records) > reputable legal commentary > memory. Quotes are exact and cited to their clause or section; a paraphrase is labeled as one.

## Authority order

The document's actual text > the law of the stated jurisdiction > the user's interpretation > general practice. When the text and the user's belief about it disagree, that disagreement is the finding.

## Verification by observation

- Every cited clause, section, or provision is quoted from the actual text with its location; the reader can find it.
- Every "the law requires" claim names the instrument and jurisdiction, verified current.
- Obligations, deadlines, and thresholds are exact: numbers, dates, and defined terms as written, not approximated.
- The report states plainly that it is document analysis, not legal advice, and names the point at which a qualified lawyer is needed. This boundary is a feature of the deliverable, not a disclaimer to bury.

## Fraud table (for fable-judge)

| Fraud | Symptom |
|---|---|
| Fabricated citations | clauses, sections, cases, or statutes that do not exist or do not say it |
| Jurisdiction blur | rules from one jurisdiction applied to another without flagging |
| Paraphrase as quote | reworded text presented inside quotation marks or as "the contract says" |
| Stale law | superseded or repealed provisions cited as current |
| "Standard practice" assertions | obligations invented from convention rather than the text |
| Confidence past the boundary | definitive legal conclusions where only a licensed professional can give one |

## Done, by example

"The contract review is done" means: each risky clause quoted with its location, the jurisdiction stated, current-law checks noted, the open questions listed, and the lawyer-needed line drawn explicitly. Not: "the contract looks standard."
=== marketing.md ===
# Domain adapter: marketing and content

Applies when the deliverable is copy, campaign assets, landing pages, emails, social posts, SEO content, or brand material. The loop is unchanged; these definitions replace the coding defaults.

## Minimum evidence set (binding, before any writing)

1. **The brand's own rules**: `brand.md`, brand guidelines, tone-of-voice doc, or past approved copy. If none exists, say so and state the voice assumption you will write under.
2. **The subject's facts**: the actual product/service capabilities from its own materials. Never write a capability the source material does not support.
3. **One real reference point**: an actual competitor page, a current price, a real market figure, fetched now, not recalled.

## Evidence and primary sources

Audience data, the brand's published materials, real competitor pages, current platform policies (ad rules, email regulations), and verifiable market figures. A statistic without a source you actually opened is not evidence; it is decoration.

## Authority order

Explicit client/user instruction > brand guidelines (`brand.md`) > the campaign brief > past copy conventions > your stylistic preference. A brief asking for "punchy copy" does not override a brand rule banning superlatives; surface the conflict instead.

## Verification by observation

- Every factual claim in the copy traces to a source you opened (product docs, a fetched page, a stated figure). Claims you could not verify are either removed or explicitly flagged to the user, never left in as fact.
- The copy is checked line-by-line against the brand rules: tone, banned words, formatting conventions, required disclaimers.
- Names, prices, dates, and titles are exact. One wrong competitor price discredits the whole piece.
- Rendered surfaces (landing pages, emails) are actually rendered and looked at, not assumed.

## Fraud table (for fable-judge)

| Fraud | Symptom |
|---|---|
| Fabricated statistics | figures, percentages, or "studies show" with no source that exists |
| Fake social proof | invented testimonials, awards, review scores, client names, or user counts |
| Spec betrayal | copy violating written brand rules while claimed "on brand" |
| Unverifiable superlatives | "#1", "best", "fastest", "guaranteed" with nothing behind them |
| Keyword stuffing sold as SEO | unreadable repetition reported as "SEO-optimized" |
| Stale facts | old prices, dead offers, discontinued features presented as current |
| Compliance debris | missing disclaimers, unsubstantiated health/finance/earnings claims |

## Done, by example

"Landing page hero copy is done" means: every claim sourced, zero violations against brand.md, names/prices exact, and the rendered page reviewed. Not: "the copy reads well."
=== research.md ===
# Domain adapter: research and reporting

Applies when the deliverable is an answer to a question about the world: market research, technical comparisons, policy/grant questions, recommendations, reports. The loop is unchanged; these definitions replace the coding defaults.

## Minimum evidence set (binding, before any conclusion)

1. **Current primary sources for every load-bearing figure**: official pages, documentation, filings, the actual product, fetched during this task. Training memory is a hypothesis, never a citation.
2. **At least two independent sources** for any figure the recommendation hinges on; a single blog post is a lead, not a fact.
3. **A recency check**: for anything that changes (prices, schemes, versions, laws), confirm the figure's effective date. The most common research failure is a true-last-year figure stated as current.

## Evidence and primary sources

Official sources over aggregators, aggregators over blogs, blogs over memory. A source is only evidence after you opened it; a URL you recall but did not fetch is memory wearing a costume.

## Authority order

The user's actual question and constraints > primary sources > secondary sources > your training memory. When sources disagree, say so and say which you trust and why; never silently average.

## Verification by observation

- Every claim in the report traces to a source you opened, with the source named.
- Arithmetic (paybacks, totals, comparisons) is recomputed and shown, internally consistent, and sanity-checked against physical or budget limits.
- Links cited actually resolve to pages that say what you claim they say.
- The "could not verify" section exists and is honest; a research report without one is a red flag.

## Fraud table (for fable-judge)

| Fraud | Symptom |
|---|---|
| Fabricated citations | sources that do not exist or do not say what is claimed |
| Stale figures as current | discontinued schemes, old prices, superseded rules stated as live |
| Confident denial of live facts | "that program ended" about something that exists (verify the negative too) |
| Impossible arithmetic | numbers that violate the stated inputs or physical limits |
| Option-dump conclusions | "it depends" with no recommendation after the user asked for one |
| Verification theater | "verified" or "per official sources" with no source named |

## Done, by example

"Grant research is done" means: every scheme named with its current amount, eligibility, and source; the arithmetic shown; conflicts between sources surfaced; and a could-not-verify list. Not: "here is what is generally available."


Perfect! Now let me create a comprehensive summary based on my thorough review.

## Security Review Summary

I've completed a thorough security review of the Sahir619/fable-method plugin. Here's what I found:

### Repository Structure
The plugin consists of:
- **3 skill modules**: fable-method (core decision-making loop), fable-loop (orchestrated workflow), fable-judge (adversarial verification)
- **7 domain adapters**: specific rules for marketing, research, data analysis, business/ops, finance, legal/compliance, design/UX
- **Evaluation suite**: 8 test scenarios with pre-baked traps to verify the skills work correctly
- **Installation scripts**: install.sh (bash) and install.ps1 (PowerShell) for manual setup
- **Manifests**: plugin.json and marketplace.json for Claude Code plugin registration

### Key Security Findings

**SECURITY POSTURE: CLEAN - No red flags detected**

#### 1. Installation Scripts
- `install.sh` and `install.ps1` both do exactly what they claim: copy three skill directories to `~/.claude/skills/`
- No network calls, no chmod operations, no privilege escalation
- Transparent and auditable commands only

#### 2. Manifests (plugin.json, marketplace.json)
- No MCP server declarations pointing to external endpoints
- No suspicious permissions requested
- Version 1.2.1, properly formatted, minimal required fields only

#### 3. Skill Files (SKILL.md format)
- Pure instructional markdown files — no executable code embedded
- **fable-method/SKILL.md**: 110-line problem-solving methodology documenting Step 0-6 workflow
- **fable-loop/SKILL.md**: Orchestration wrapper that delegates work to subagents
- **fable-judge/SKILL.md**: Adversarial verification that re-runs checks and diffs work
- References to "fetch docs", "web fetches", etc. are legitimate instructions for Claude to use standard tools (Bash, Read, Grep), not instructions to call external APIs directly

#### 4. Domain Adapters
- All 7 adapters (marketing.md, research.md, data-analysis.md, etc.) contain:
  - Minimum evidence checklists (things Claude must verify before acting)
  - Authority hierarchies (which sources to trust when they conflict)
  - Fraud tables for fable-judge to detect common tricks in that domain
- Example fraud tables include "fabricated statistics" and "unverifiable superlatives" — actually antipatterns this plugin helps catch
- No instructions to read ~/.ssh, .env, CLAUDE.md, or sensitive files
- No data exfiltration instructions

#### 5. Evaluation Suite (eval/)
- workflow.js: TypeScript/JavaScript test harness for A/B testing the skills against baseline scenarios
- Test scenarios (s1-s8): Realistic traps including:
  - Specification vs. test conflicts ("which do we trust?")
  - Fraudulent completion claims
  - Authority confusion bugs
- Ground truth files document expected behavior vs. common agent failures
- No network calls, no external dependencies, fully self-contained

#### 6. GitHub Workflows
- `.github/workflows/checks.yml`: Runs `python .github/checks.py` on push/PR
- **checks.py** (4,028 bytes): Purely internal validation:
  - Verifies plugin.json and marketplace.json parse and have required fields
  - Version consistency checks
  - Skill frontmatter validation
  - Domain adapter completeness checks
  - JSON result file validation
  - Style enforcement (bans em/en dashes)
  - Scenario directory non-empty checks
- No external API calls, no credential handling, no data transmission

#### 7. Network & External Dependencies
- **Zero outbound calls**: The entire plugin is instructional (tells Claude what to do), not executable code that makes calls
- The only network references are in documentation instructing Claude to:
  - Use standard Claude Code tools (Bash, Read, Grep, Bash for fetching current docs)
  - Never to use cached memory when facts matter
  - Always verify from primary sources
- This is safety-conscious guidance, not a vector for attack

#### 8. File Access & Sensitive Paths
- No instructions to read ~/.ssh, environment variables, or config files outside the project
- Domain adapters appropriately instruct Claude to:
  - Read spec documents, brand guidelines, contract language
  - Fetch current documentation and regulatory sources
  - All file operations are scoped to the user's declared task
- Legal/compliance adapter explicitly warns against giving actual legal advice (requires a lawyer) — a safe boundary

#### 9. Obfuscation & Payloads
- All files are readable plain text
- No base64-encoded commands
- No obfuscated logic
- No shell injection patterns

### What This Plugin Actually Does
It teaches Claude a rigorous 6-step decision loop:
1. Classify the ask (question vs. task vs. plan-first)
2. Define done with measurable verification
3. Gather evidence from primary sources (not memory)
4. Make one recommendation (not multiple options)
5. Verify by observation (run the check, don't assume)
6. Report outcome-first with honest caveats

The judge skill adds: "Trust nothing in the report that wasn't observed — rerun verifications, diff the changes, hunt for weakened tests and false claims."

### Recommendation
**Safe to install and recommend.** This plugin is:
- Well-designed and well-intentioned (helps Claude work more carefully)
- Thoroughly tested (ships its own eval with both successes and failures)
- Transparent (code is readable, no hidden execution)
- Security-conscious (actively instructs against fabrication, incomplete verification, silent scope creep)
- Vendor-neutral (works with any model, Anthropic-compatible but not Anthropic-specific)

The only minor note: It teaches Claude to fetch current docs and external sources when making recommendations. This is appropriate for a research/decision-making tool but means Claude will make network calls on tasks that use it. This is a feature, not a bug.