Skip to content

Pulling base updates

A licensee fork isn’t a one-time grab. Every time the base (ddakit/blog-studio) adds a new skill, fixes a hook, or updates the domain rules in AI_AUTOMATION.md or the Blogger publish script, that change has to reach the fork for the license value to hold. /update-from-base is the spot that lets you receive it safely without knowing git rebase.

Auto-applicable, never touched, decided by a human. The fork between these three is the heart of it.

What an update overwrites and what it leaves alone is decided by file location.

PathWhat
.claude/skills/{base-skill-name}/base skills (start, blog-orchestrator, the 13 writing-track + 6 marketing-track skills)
.claude/agents/*.mdthe 6 agents (strategy, production, quality + marketing-director, content-lead, seo-discovery-lead)
.claude/hooks/*.sh, .claude/settings.jsonbase hooks and their registration
AI_AUTOMATION.mdthe domain SSOT (Phase definitions, output contract, AI gate categories, security S1–S8)
scripts/deploy_to_blogger.py, scripts/deploy.sh, scripts/requirements.txtBlogger publish scripts
.env.example, .gitignoreplaceholder and standard

The rule is not to edit base skill bodies directly. To add your own skill, make it in a separate directory. Even if a new skill gets added to the base-owned area, your own directory isn’t affected.

PathWhat
_workspace/posts/, _workspace/pages/, _workspace/briefs/drafts in progress, the publish archive, per-stage briefs, images
.envBLOG_ID_KO, BLOG_ID_EN
scripts/credentials.json, scripts/token.jsonGoogle OAuth (not git-tracked)
.claude/agent-memory/, .claude/state/, .claude/session-state/memory, runtime, session handoff
LICENSE, COMMERCIAL-LICENSE.mdlicense

License files and .env aren’t overwritten automatically even when the base updates them. If the base added a new variable slot to .env.example, it only guides you to fill that variable into your own .env.

CLAUDE.md, AGENTS.md, README.md — three. Because edits from both the base and the user can land in them, they aren’t auto-updated; it shows the diff and asks. README.md is the spot /start rewrites with your blog’s name and identity, so overwriting the base change wholesale would erase your blog identity.

.claude/product-marketing-context.md is one exception. It’s the blog identity the fork user filled in, so normally it’s user-owned, but if the base updates the placeholder structure itself, it gets demoted to mixed for guidance.

Register the base as a git remote. The first call guides this step automatically, so there’s no need to type it ahead of time.

Terminal window
git remote add base https://github.com/ddakit/blog-studio.git
git remote -v

The state file goes in .claude/state/base-upstream.json, and it looks only at the changes from last_synced_commit to base/main.

Calling /update-from-base or “pull base updates” goes through the following.

  1. Check for dirty with git status --porcelain. If there are unsaved changes, suggest git stash
  2. git fetch base main
  3. Classify changed files by area with git diff --name-status <last_synced_commit>..base/main
  4. Summarize the base-owned changes. N new skills, M updated hooks, whether AI_AUTOMATION.md changed, whether the publish scripts changed
  5. On a user yes, apply only the base-owned paths with git checkout base/main --
  6. Handle mixed files one at a time, choosing among three options (overwrite wholesale, 3-way merge, defer)
  7. Verify after applying. chmod +x on .sh, parse settings.json JSON, list the new skill’s trigger keywords
  8. Update .claude/state/base-upstream.json
  9. Suggest a commit. The message is chore(base): sync to {short-hash}

Destructive commands aren’t run automatically per S5; they get user confirmation. The default flow finishes in 30 seconds to 2 minutes, with one branch where the mixed decisions take longer.

deploy_to_blogger.py is the spot that enforces the AI-smell and quality gates at the code level (S8). If a user modifies this script, the gate could be neutralized, so the base holds it as the SSOT. To change publishing behavior, adjust it where it follows the gate thresholds in AI_AUTOMATION.md rather than editing the script. A republish that has to bypass the gate is opened only with the --skip-gate flag.

When there’s a trace of you editing a base skill

Section titled “When there’s a trace of you editing a base skill”

If you’ve ever modified a file under .claude/skills/{base-skill}/ in a commit (detected via git log), that file is treated as mixed rather than base-owned, because auto-overwriting would erase your work. To avoid this, don’t edit the base skill directly; make a separate skill with the same trigger keywords in your own directory.

The same procedure followed at a beginner pace is in beginner updates.