arbiterforge/codearbiter-context-creation
The brownfield back-fill. Routed to by /create-context, and by startup when .codearbiter/CONTEXT.md lacks the <!--INITIALIZED--> body marker but source code exists. Six gated phases — pre-flight, scout dispatch, synthesis, gap interview, write, lock. Reads the existing codebase through parallel scouts, drafts every surviving project-state doc, resolves gaps with the user, and locks the project as initialized.
npx skills add https://github.com/arbiterForge/codeArbiter --skill context-creation
Wrap an existing codebase in project state, without guessing. Routed to by /create-context, and by startup when .codearbiter/CONTEXT.md exists but carries no <!--INITIALIZED--> body marker and meaningful source code is present. When no meaningful source exists, this is the wrong skill — route to decompose instead.
This back-fills from existing source. It complements $ca-init, which scaffolds an empty .codearbiter/ for a fresh project; here the docs are derived from what is already on disk.
Read these, or STOP and surface the gap — never guess project identity or a command:
<project-root>/.codearbiter/CONTEXT.md — if it already carries <!--INITIALIZED-->, context exists. Stop and route to normal operation.The excluded set (not "meaningful source"): .git/, .codearbiter/, .claude/, AGENTS.md, CLAUDE.md, README.md, LICENSE, .gitignore, .gitmodules, and standard tooling dotfiles (.editorconfig, .prettierrc, etc.). Meaningful source MUST exist beyond it.
Confirm the repository is a brownfield codebase safe for scout-based extraction:
<!--INITIALIZED--> is absent from CONTEXT.md.src/, backend/, frontend/, lib/, app/, or equivalent).State the finding to the user: existing source detected, beginning scout-based extraction.
Gate: <!--INITIALIZED--> absent AND meaningful source present. If the marker is present, stop and route to normal operation. If no meaningful source exists, stop and route to decompose. Neither condition met → do not proceed.
A scout is a restricted, read-only role, not an unconstrained
general-purpose agent. A scout reads one targeted slice of the codebase and
returns a structured findings report — file paths, line numbers, and named
values only, never raw code excerpts. Scouts are internal to this skill; they
are never invoked from a command.
Dispatch six isolated scout subagents simultaneously. If the active host
cannot provide isolated subagents, BLOCK context creation and report the host
capability gap. The general inline-role fallback does not apply here: this
skill's report-only synthesis contract depends on the orchestrator never
loading the scouts' raw source into its own context.
Each reads only its assigned slice:
package.json, lockfiles, pyproject.toml, requirements.txt, go.mod, Cargo.toml, *.gemspec, Gemfile. Report languages, runtime versions, frameworks, key dependencies, the dependency manager, license fields. Additionally report, at the repository root only: which of package.json / pyproject.toml / Cargo.toml / composer.json carry a version field (candidate release manifests), which of CHANGELOG.md / CHANGES.md / HISTORY.md are present (candidate changelogs), and any existing tag naming convention visible in the repo (e.g. a v* tag) — the inputs Phase 3/5 use to draft .codearbiter/release-targets.md..github/workflows/, .gitlab-ci.yml, Jenkinsfile, .circleci/config.yml), Dockerfile*, docker-compose*.yml, Makefile, *.tf, IaC. Report CI/CD platform, build/test/lint commands, deployment targets, environment names, containerization, IaC tool.main.ts, index.ts, app.py, server.go), and imports in entry points only. Report component list, entry points, module boundaries, architectural pattern, public interfaces.auth*, middleware*, guard*, jwt*, session*, oauth*), crypto import lines, secret-loading sites (process.env, os.environ, vault/KMS call sites — paths and line numbers only, never values), .env.example (never .env). Report auth mechanism, crypto libraries, secret-loading patterns (paths + lines, no values), vault/KMS integration, hardcoded-secret risk files (paths only).vitest.config.*, jest.config.*, pytest.ini, Makefile test flags), coverage config. Report test framework, runner command, coverage tool, coverage thresholds in config, naming convention, approximate test count by type, fixtures.migrations/, drizzle/, alembic/, db/migrate/), schema definitions (schema.ts, *.prisma, *.sql, models/), ORM config, DB connection config (keys only, never credentials). Report database type, ORM/query builder, entity names, migration tool, approximate entity count, multi-tenancy patterns.The orchestrator reads only the scout reports in later phases — never the raw source — to preserve working context. A scout that finds nothing returns an explicit "not found" report, never silence.
Content hashes: Scouts additionally emit a git hash-object <path> content oid per cited file in the hash field of their evidence entry. The scout already Read those files — no additional pass is needed, and no raw content is forwarded to the orchestrator.
Gate: all six scout reports returned. A missing report is a blocking gap — do not proceed with an incomplete picture. Re-dispatch a failing scout before Phase 3.
Draft every surviving project-state doc from the six reports, working only from the reports. Map source to destination:
| Scout source | Destination |
|---|---|
| A (tech stack), B (build/test/lint commands), E (test runner) | tech-stack.md |
| C (architecture), E (structure) | coding-standards.md |
| D (security) | security-controls.md (thin) |
| A (candidate manifest, candidate changelog, tag convention) | .codearbiter/release-targets.md |
| All scouts | CONTEXT.md (project identity, purpose, scope, NOT-building) |
Classify every finding by confidence:
"jest" in package.json). Write it as fact.[CONFIRM-NN] placeholder.Every [CONFIRM-NN] carries: a sequential ID, one sentence on what is unknown, why it matters, and what would resolve it. IDs are sequential with open-questions.md.
.codearbiter/release-targets.md is HIGH-confidence only when Scout A found exactly one candidate manifest and exactly one candidate changelog at the repository root. Draft the row then, in the grammar ${CLAUDE_PLUGIN_ROOT}/hooks/_releaselib.py's module docstring declares — a single-target project needs only prefix, manifest, changelog, payload:
<!-- release-targets -->
[app]
prefix: v
manifest: package.json
changelog: CHANGELOG.md
payload: .
<!-- /release-targets -->
(prefix defaults to v unless Scout A found a different existing tag convention; payload is . for a single-package repository.) Zero, or more than one, candidate manifest or changelog is LOW confidence — the same "no signal, or conflicting signals" rule above — and gets a [CONFIRM-NN] instead of a guessed row; this doc is never scaffolded from an ambiguous scan, and the file is simply not written until the gap is resolved in Phase 4.
Gate: every surviving doc drafted; every low-confidence inference carries a [CONFIRM-NN]. No silent omission. A domain with no scout signal gets a doc with a [CONFIRM-NN] for the whole section — never an empty file.
Resolve [CONFIRM-NN] items with the user. Ask only what the scouts could not answer with HIGH confidence.
[CONFIRM-NN] list grouped by category — gaps the scan could not resolve.open-questions.md; if the answer is vague, challenge it and demand a concrete answer before recording anything.Gate: every [CONFIRM-NN] has exactly one outcome — resolved (replaced with content) or explicitly deferred (marked and recorded in open-questions.md). No item is silently dropped. Do not proceed with unacknowledged gaps.
Write the surviving docs to <project-root>/.codearbiter/. Every doc carries actual content — no unresolved placeholder may remain where a value was determined:
| File | Content |
|---|---|
| CONTEXT.md | Project identity, purpose, scope, primary users, NOT-building. Frontmatter MUST include arbiter: enabled (the activation flag the SessionStart hook keys on) and stage: set to a single maturity number (default 1; the user may raise it if the project is further along). |
| tech-stack.md | Languages, frameworks, test runner, lint command, build command, coverage command, issue-tracker command (e.g. gh issue create). |
| coding-standards.md | Structural patterns, naming conventions, style rules. |
| security-controls.md | Thin: auth mechanism, banned crypto primitives, secret-loading stance. Only what a security boundary actually requires. |
| open-questions.md | Every deferred [CONFIRM-NN] in CONFIRM-NN: <description> form. |
| open-tasks.md | Create the file with its heading only. Every task goes in through the board helper, one call per item — python3 "${CLAUDE_PLUGIN_ROOT}/hooks/taskwrite.py" add "<task>" — never by writing entries into the file directly (B-18). The helper owns the board schema the SessionStart hook and the statusline parse, so a backlog seeded this way cannot drift from it; and once open-tasks.md is enrolled in the protected-state registry, a direct write is refused outright, which would leave a Write-tool instruction here unfollowable. If scouts found no backlog, the heading-only file stands as the stub. |
| overrides.log | Empty append-only audit log, created so /override has a sink. |
| release-targets.md | Conditional, unlike every other row above: written ONLY when Phase 3 drafted it at HIGH confidence (exactly one candidate manifest, exactly one candidate changelog) or Phase 4 resolved its [CONFIRM-NN] to a concrete row. Left unwritten otherwise — /release's own back-fill lane (or a later context-creation run, once the ambiguity resolves) is the sanctioned way to create it, never a guess made here. This file is marker-gated protected state; it needs the authoring marker below, unlike every other row in this table. |
Authoring marker — required for release-targets.md only. That path is enrolled in the protected-state registry as marker-gated (hook H-22), so a Write against it is refused unless a fresh authoring marker exists. This lane is a sanctioned author of it, so it mints one immediately before the write and removes it immediately after — the same one-pass shape /release's back-fill lane uses:
mkdir -p "$(git rev-parse --show-toplevel)/.codearbiter/.markers"
touch "$(git rev-parse --show-toplevel)/.codearbiter/.markers/release-targets-authoring"
Write the file, then:
rm -f "$(git rev-parse --show-toplevel)/.codearbiter/.markers/release-targets-authoring"
Skip both commands entirely when this run is not writing release-targets.md — a marker minted for a write that never happens is a 30-minute window nothing needed. No other file in the table above is enrolled, so none of them take a marker.
If scouts found existing decision records (docs/decisions/, adr/), summarize them as entries under .codearbiter/decisions/ in the standard ADR format. If a record cannot be fully parsed, summarize what is known, flag the uncertainty, and note the source path for review.
Provenance and code-map (small addition, not a Phase 5 rebuild):
.codearbiter/.provenance/<doc>.json via _provenancelib.write_provenance and new_record. Each entry carries: path (repo-relative), hash (the scout's git hash-object oid), drift_trigger (from _provenancelib.classify_source(path)), and the claims array with lines, claim, and confidence drawn from the scout evidence..codearbiter/code-map.md (concern → path → ≤1-line role) from Scout C (architecture) evidence. Use concern headings (## <concern>) and column-0 bullets (- \path\ — role). Keep it coarse — module/concern granularity only, no full file listing.Do NOT scaffold any cut doc — see ${CLAUDE_PLUGIN_ROOT}/includes/cut-docs.md for the canonical never-scaffold list. Maturity lives in the stage: frontmatter of CONTEXT.md, not a separate file.
Gate: every surviving doc written; CONTEXT.md frontmatter carries arbiter: enabled and stage:; no resolved value left as a placeholder. Deferred [CONFIRM-NN] items are acceptable only in open-questions.md.
Lock the project state as initialized and return to normal orchestration:
<!--INITIALIZED--> marker into the body of CONTEXT.md..codearbiter/ and display the populated tree.CONTEXT.md (with arbiter: enabled frontmatter and the <!--INITIALIZED--> body marker), tech-stack.md, coding-standards.md, security-controls.md, open-questions.md, open-tasks.md, overrides.log.$ca-feature available to begin work. Deferred questions live in open-questions.md.Gate: arbiter: enabled set and <!--INITIALIZED--> present in CONTEXT.md; every required file present and non-empty. Do not close this skill without confirming both markers are written.
<!--INITIALIZED--> while any [CONFIRM-NN] is unaddressed — every gap must be resolved or explicitly deferred to open-questions.md first.[CONFIRM-NN] by guessing — surface the question to the user or defer it.${CLAUDE_PLUGIN_ROOT}/includes/cut-docs.md for the canonical never-scaffold list. Maturity is the stage: frontmatter number in CONTEXT.md.CONTEXT.md already carries <!--INITIALIZED--> — stop and route to normal operation.Take arbiterforge/codearbiter-context-creation from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.