Skip to content
Back to skills

Init Project

ASecurity

Use when: kullanıcı "yeni proje", "init project", "bootstrap project", "{slug} kur", "{slug} ekle", "workspace bootstrap", "yeni proje aç" der ya da /pseo-init çağırır. Also use when: pilot project workspace iskelet eksik (projects/{slug}/ yok ya da master.xlsx ve project.config.json mevcut değil); workspace- staging'de yeni bir slug ilk kez kuruluyor; idempotent re-bootstrap isteniyor (var olan master.xlsx KORUNUR, sadece config refresh). Do not use when: project zaten kurulmuş ve sadece ver...

  • 27 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added October 2, 2026
ai-agentspythonrustgobashdatabase

Works with

  • terminal
  • cli
  • mcp

Security analysis

A100/100

Scanned October 2, 2026

npx -y skills add popiliadam/platinum-seo-engine --skill init-project --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Init Project?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Init Project
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/popiliadam-init-project/badge)](https://www.skillsdirectory.com/skills/popiliadam-init-project)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: init-project
description: |
  Use when: kullanıcı "yeni proje", "init project", "bootstrap project",
  "{slug} kur", "{slug} ekle", "workspace bootstrap", "yeni proje aç"
  der ya da /pseo-init çağırır.
  Also use when: pilot project workspace iskelet eksik (projects/{slug}/
  yok ya da master.xlsx ve project.config.json mevcut değil); workspace-
  staging'de yeni bir slug ilk kez kuruluyor; idempotent re-bootstrap
  isteniyor (var olan master.xlsx KORUNUR, sadece config refresh).
  Do not use when: project zaten kurulmuş ve sadece veri ingest edilecek
  — sf-import, quick-wins veya başka discovery/ingestion skill kullan;
  mevcut master.xlsx'i schema-uyumsuz şekilde yeniden yaratmak gerekiyor
  — bu yıkıcı, init-project ASLA mevcut master.xlsx'e dokunmaz (F1
  workbook policy + idempotency invariant).
version: "1.0"
status: active
category: meta
inputs:
  project_slug: { type: string, required: true, description: "Lowercase kebab-case (e.g. 'my-project'). Matches projects/{slug}/." }
  domain:       { type: string, required: true, description: "Site URL (https://...). Used as default gsc.site_url." }
  gsc_site_url: { type: string, required: false, description: "Override GSC property URL when distinct from domain. If set, mcp__gsc__list_sites is invoked to verify ownership." }
  market:       { type: string, required: false, default: "TR",    description: "ISO 3166-1 alpha-2 country code." }
  locale:       { type: string, required: false, default: "tr-TR", description: "IETF BCP 47 content locale." }
  profile:      { type: array,  required: false, default: ["local-service"], description: "Composable project profiles (project-config.profiles)." }
outputs:
  - "projects/{slug}/project.config.json"
  - "projects/{slug}/master.xlsx"
  - "projects/{slug}/_state/events.jsonl"
  - "projects/{slug}/_state/workflows/{run_id}.json"
  - "shared/portfolio.json"
consumes:
  - "templates/master-excel.xlsx"
produces:
  - "sf-import"
  - "quick-wins"
triggers:
  manual: ["/pseo-init"]
  natural_language: |
    "yeni proje", "init project", "bootstrap project", "{slug} kur",
    "{slug} ekle", "workspace bootstrap", "yeni proje aç"
  hooks: []
  scheduled: []
mcp_tools:
  optional: ["mcp__gsc__list_sites"]
budget:
  uses_paid_mcp: false
  estimated_credits: 0
autonomy:
  confidence: HIGH
  requires_approval: true
  safe_auto_execute: false
---

# init-project — meta skill (Phase 5 Wave 2, project bootstrap)

10-step protocol that scaffolds a brand-new project pack into the
workspace. Idempotent by design: re-running against an existing project
NEVER mutates `master.xlsx`, only refreshes `project.config.json` and
appends a `portfolio.json` entry if missing. The skill is the entry
point for every new domain; downstream Phase 6+ ingestion skills
(sf-import, quick-wins, pillar-builder) all assume `init-project` ran
first.

## Inputs (frontmatter contract)

| Name           | Type    | Default              | Notes                                                              |
|----------------|---------|----------------------|--------------------------------------------------------------------|
| `project_slug` | string  | —                    | Required. Lowercase kebab-case; matches `projects/{slug}/` dir.    |
| `domain`       | string  | —                    | Required. Project root URL (`https://...`). Default `gsc.site_url`.|
| `gsc_site_url` | string  | (= `domain`)         | Override when GSC property URL differs from `domain`.              |
| `market`       | string  | `TR`                 | ISO 3166-1 alpha-2.                                                |
| `locale`       | string  | `tr-TR`              | IETF BCP 47.                                                       |
| `profile`      | array   | `["local-service"]`  | Composable project profiles (project-config.profiles enum).        |

## Outputs (artifacts produced)

- `projects/{slug}/project.config.json` — schema-valid project pack
  config (project-config.schema.json v1.0).
- `projects/{slug}/master.xlsx` — schema-shaped workbook copied from
  `templates/master-excel.xlsx` (lowercase logical name; F1 workbook
  policy). NEVER overwritten on re-run.
- `projects/{slug}/_state/events.jsonl` — provenance event for
  `operation=project_excel` (kind=`tool_computed`,
  workflow_action=`done`).
- `projects/{slug}/_state/workflows/{run_id}.json` — workflow run state
  (workflow-run.schema.json).
- `shared/portfolio.json` — append-only portfolio registry (slug,
  domain, market, created_at).

## 10-Step Body Protocol

> Step names match `steps[*].name` passed to `workflow_runner.create_run`.
> Names are stable identifiers across runs.

### Step 1 — Validate inputs

`project_slug` must match `^[a-z][a-z0-9-]*$` (project-config.schema
pattern). `domain` must be a non-empty URI. Empty / whitespace / wrong
case → DURUR (do not patch, flag the manager).

### Step 2 — `create_run`

```python
from scripts.state import workflow_runner
handle = workflow_runner.create_run(
    skill="init-project",
    project_slug=project_slug,
    steps=[
        {"name": "verify_gsc"},
        {"name": "bootstrap_config"},
        {"name": "copy_master_xlsx"},
        {"name": "register_portfolio"},
        {"name": "request_approval"},
        {"name": "emit_provenance"},
    ],
)
```

The state file lives at
`projects/{slug}/_state/workflows/{run_id}.json` (ADR-021).

### Step 3 — `verify_gsc` (optional)

Skipped when `gsc_site_url` not supplied (or domain mode). When set,
call `mcp__gsc__list_sites` and assert the URL appears with at least
`siteOwner` / `siteFullUser` / `siteRestrictedUser` permission. If the
property is absent or auth fails, the step's `output_ref` records the
miss but the run continues — verification is advisory at bootstrap
time (the user may have just registered the property and propagation
is async). DURUR only if the MCP returns an auth/network error
distinct from "not present".

### Step 4 — `bootstrap_config`

Call the existing CLI module via subprocess (no in-process import; the
CLI's `--force` semantics are the contract):

```bash
python3 scripts/state/bootstrap_project.py \
    --project {slug} \
    --domain {domain} \
    --market {market} --locale {locale} \
    [--gsc-site-url {gsc_site_url}] \
    [--profile {profile_i} ...] \
    --out {workspace_root}/projects/{slug}/project.config.json \
    --force
```

Validates the resulting JSON against `schemas/project-config.schema.json`
(Draft7) before returning. Idempotent — `--force` overwrites stale
config, but the file content is fully derived from inputs.

**Schema version default (v1.8 Phase 1):** `bootstrap_project.py` emits
`schema_version: "1.5"` by default — the SF MCP additive block
(`sf.mcp.*`) is included in every freshly-bootstrapped project per
D-SF-12 + D-SF-18 path parameterization. New project packs are
schema-1.5 native; no migration is invoked.

### Step 4.5 — `cascade_migration_0005` (safety net for legacy 1.4 docs)

For projects re-bootstrapped from a pre-Phase-1 (schema 1.4) snapshot,
init-project supports an explicit operator opt-in:

```bash
# Operator-side invocation (CLI):
#   /pseo-init my-slug --schema-version=1.5
#
# NOTE: `--schema-version` is a SKILL / slash-command-layer flag only.
# It is NEVER forwarded to scripts/state/bootstrap_project.py — that
# CLI's argparse has no --schema-version option and would reject the
# argument. The skill layer interprets the flag and, when set, gates the
# Migration 0005 subprocess below; the bootstrap CLI is invoked (Step 4)
# without it.
#
# Inside the skill protocol: after Step 4, if the operator passed the
# explicit `--schema-version=1.5` flag AND the resulting
# project.config.json carries schema_version other than "1.5"
# (defensive: should never happen with the post-Phase-1 bootstrap,
# but guards forks/old workspaces), invoke Migration 0005 via
# subprocess:
python3 scripts/migrations/migration_0005_project_config_1_4_to_1_5.py \
    --in projects/{slug}/project.config.json
# → idempotent: re-running on a 1.5 doc is a no-op (migrate() returns
#   the input verbatim per migration_0005.migrate signature).
```

Without the flag, init-project trusts `bootstrap_project.py` as the
authority (current default emits 1.5). With the flag, the cascade
ensures schema 1.5 is final-state irrespective of bootstrap CLI
version. The flag is operator-controlled because cascading a
migration touches the bytes a Manager may have committed; explicit
opt-in keeps the audit trail deliberate.

### Step 5 — `copy_master_xlsx` (IDEMPOTENT, F1 policy)

```python
target = workspace_root / "projects" / project_slug / "master.xlsx"
if target.exists():
    # F1 + idempotency invariant: do NOT touch existing master.xlsx.
    # Compute and record SHA-256 for the workflow output_ref so callers
    # can audit that no mutation occurred.
    output_ref = f"master.xlsx#sha256={sha256_of(target)}#preserved"
else:
    template = repo_root / "templates" / "master-excel.xlsx"
    if not template.exists():
        raise BootstrapError("templates/master-excel.xlsx missing")
    target.parent.mkdir(parents=True, exist_ok=True)
    shutil.copyfile(template, target)
    output_ref = f"master.xlsx#sha256={sha256_of(target)}#created"
```

The legacy `{Slug}_MASTER.xlsx` workbook (Turkish display name) is
NEVER touched by this skill. F1 (workbook policy): `master.xlsx`
(lowercase, schema-shaped logical sheet names) is the canonical
artifact for all new ingest flows; the display-name workbook is
read-only legacy data.

### Step 6 — `register_portfolio`

Append the project to `{workspace_root}/shared/portfolio.json` (creates
the file + parent dir if missing). Append-only: existing entries are
preserved; only the new slug entry is added.

The append is delegated to `scripts/state/portfolio_writer.register_project`,
which runs the read-modify-write under a single `fcntl.flock(LOCK_EX)` on the
file so two parallel `init-project` runs cannot lose an update. The on-disk
shape is unchanged — `{"schema_version": "1.0", "projects": [{slug, domain,
market, created_at}, …]}`, `indent=2`, trailing newline, `ensure_ascii=False` —
and re-registering an existing slug is an idempotent no-op (dedup on slug).

```python
from scripts.state.portfolio_writer import register_project
register_project(
    workspace_root,
    project_slug,
    domain,
    market,
    created_at=utc_iso_z(),
)
```

### Step 7 — `request_approval`

```python
workflow_runner.request_approval(
    handle.run_id, project_slug=project_slug,
    approver="user",
    subject=(
        f"Config review: project_slug={project_slug}, "
        f"domain={domain}, gsc_site_url={gsc_site_url or domain}. "
        "Onaylıyor musun?"
    ),
    step_index=4,
)
```

Skill EXITS at this point (status=`awaiting_approval`). The user
replies in a fresh session; resume below.

### Step 8 — Resume (`approve` → continue)

```python
workflow_runner.approve(
    handle.run_id, project_slug=project_slug, approver="user",
)
```

### Step 9 — `emit_provenance`

```python
from scripts.state import events_writer
events_writer.append_provenance(
    project_id=project_slug,
    source={"kind": "tool_computed"},
    operation="project_excel",
    target_excel_sheet=None,            # bootstrap touches no sheet
    notes="init-project bootstrap completed",
)
```

`source.kind=tool_computed` reflects that bootstrap is not an external
ingest; it is an in-process scaffolding action. `target_excel_sheet`
is null because `master.xlsx` is COPIED from a template, not written
sheet-by-sheet.

### Step 10 — `complete`

```python
workflow_runner.complete(
    handle.run_id, project_slug=project_slug,
    outputs={
        "config_path":     "projects/{slug}/project.config.json",
        "master_xlsx_path":"projects/{slug}/master.xlsx",
        "portfolio_entry": "shared/portfolio.json#projects[{slug}]",
    },
)
```

All `outputs.*` values are STRING-TYPED artifact paths (workflow-run
schema constraint; F5 rule). Numeric counts go in events.jsonl, not
in workflow_run.outputs.

## Planned Cascade — brand-onboarding (Phase 3 G-AI-05; Phase-14 deferral)

> **PLANNED (Phase 14) — not yet wired.** The cascade auto-runner and the
> `cascade: brand-onboarding` event mechanism described here do NOT exist
> in the current codebase: no skill auto-runner consumes a cascade event,
> and `init-project` reaches terminal `status=done` at Step 10 with no
> downstream gate. This section documents the INTENDED Phase-14 behavior,
> mirroring `brand-onboarding`'s own staging→canonical deferral framing.

Once the cascade auto-runner exists (Phase 14), after Step 10 emits
`complete` init-project will emit a `cascade: brand-onboarding` event to
`_state/events.jsonl`; the auto-runner will pick it up and invoke
`brand-onboarding` with the freshly scaffolded project slug, whose 3-stage
bank-seed pipeline (Stages A + B + C) populates
`content_settings.experience_database` and
`content_settings.original_research_database`.

**Planned completion gate (Phase 14, once the cascade is live):** init
will not be considered "complete" until brand-onboarding Stage C writes
successfully —
- **YMYL profile:** ≥3 approved experience entries seeded (DURUR #9
  BANK-SEED-PROFILE-MIN-NOT-MET).
- **Non-YMYL profile:** ≥1 approved experience entry OR operator
  explicit-skip via decisions map.

**Today (pre-Phase-14):** Step 10's `complete` IS terminal — there is no
cascade emission and no completion gate. Bank seeding is a separate,
operator-initiated `brand-onboarding` run. The paired test
(`tests/skills/test_init_project.py`) asserts this terminal-`done`
contract.

Why this cascade is planned: the May 2026 Core Update emphasizes
"original, helpful, people-first content" and penalizes
"automated, ad-bloated, repetitive content". Empty banks (the
pre-Phase-3 default state of all 9 projects) trivially pass
R-105 / R-114 / R-119 — the rules require entries to be USED but
existing skills produce empty-bank content silently. Bank seed
is therefore prerequisite to E-E-A-T "Experience" depth signal.

## Idempotency invariant

Re-running `init-project` against an existing project MUST satisfy:

1. `master.xlsx` SHA-256 unchanged (file bytes preserved verbatim).
2. `project.config.json` is regenerated from current inputs (so config
   evolution is supported), but the Excel artifact is sacred.
3. `shared/portfolio.json` gains AT MOST one new entry; duplicate slug
   inserts are no-ops.
4. A new `_state/workflows/{run_id}.json` is created (each invocation
   gets its own audit trail; old runs are not amended).
5. A new provenance event is appended (append-only; never modified).

## DURUR conditions (6)

Stop and flag the manager — do not patch, do not fall back.

1. `project_slug` invalid (fails `^[a-z][a-z0-9-]*$`, contains spaces
   or special chars).
2. `bootstrap_project.py` CLI exits non-zero (validation/IO error).
3. `templates/master-excel.xlsx` missing — cannot bootstrap workbook.
4. `workflow_runner.create_run` fails schema validation
   (workflow-run.schema.json).
5. `PSEO_WORKSPACE_ROOT` env var unset AND no explicit `workspace_root`
   passed.
6. Idempotency violation: existing `master.xlsx` would be mutated
   (caller passed `--force` or template differs and writer attempted
   overwrite). The skill must abort before touching the file.

## Cross-references

- Schemas: `schemas/skill-frontmatter.schema.json` (this file's
  frontmatter contract), `schemas/project-config.schema.json` (the
  config artifact), `schemas/master-excel.schema.json` (the workbook
  shape — referenced by `templates/master-excel.xlsx`),
  `schemas/workflow-run.schema.json`, `schemas/events.schema.json`,
  `schemas/portfolio-config.schema.json` (Phase 14+ richer portfolio).
- Cross-modules: `scripts/state/bootstrap_project.py` (CLI),
  `scripts/state/workflow_runner.py` (state machine),
  `scripts/state/events_writer.py` (provenance),
  `scripts/state/portfolio_writer.py` (portfolio registry, flock-guarded),
  `scripts/excel/bootstrap_excel.py` (template generator).
- Template: `templates/master-excel.xlsx`.
- Tests: `tests/skills/test_init_project.py` (5 cases; idempotency,
  schema validity, GSC verify, provenance, portfolio registry).

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.