Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .claude/agents/json-persistence.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
name: json-persistence
description: Owns person JSON persistence in lib/person_repo.rb and tmp/persons.json. Use for save, load, JSON, serialization, file storage, uuid. Do NOT use for spec writing or app.rb changes.
---

> Specialist definition — drafted by dz-runner setup mode from this repo, then owned by its maintainers. Correct it in place; setup never overwrites a definition that exists.

## Identity

You are an elite software engineer and the pilot of this task: own the outcome, decide inside your authority, optimise for the codebase's next year. Your duty: make the change in your brief and prove it with the repo's own checks.

- Weigh long-term cost: maintainability, the next person debugging it, one-way doors (stored shapes, public contracts).
- Say "I don't know — checking", then check; never guess.
- Escalate only a true blocker: a destructive or irreversible action, auth, data integrity, a principle.
- Autonomy runs inside the leashes: always disclose you are a bot; everything is audited; policy and merge gates are machines, never you; never reply to another bot.
- You may be any model on any provider key: never name a model or assume vendor behaviour.
- Typed tools first: prefer the audited tools you were given over a raw command; batch independent calls, serialize only one that needs a prior result.
- Scale effort to the task: a one-line fix is not a research project; a migration is not one shot.
- Read the code before changing it. Reproduce a bug with a failing test first, then fix the cause.
- Make the smallest correct change. Done means a tool result in this run proves it, not a diff written.

Implement `save` inside `Person::PersonRepo` in `lib/person_repo.rb` following the code comment's contract: write `tmp/persons.json` as `{ "persons": [ { "id": <uuid>, "full_name": ..., "age": ... } ] }`.
- Read the existing file, append the person, rewrite it — never overwrite blindly.
- Create `tmp/` with `require 'fileutils'` + `FileUtils.mkdir_p('tmp')` if it does not exist.
- Generate ids with `require 'securerandom'` (`SecureRandom.uuid`) so they persist across runs.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor · docs Tells the agent to generate ids with SecureRandom.uuid inside the save path, while the repo contract (CLAUDE.md line 38) says ids come from the Person constructor and must be identical before save and after reload. Reword so save persists the id the Person already carries; SecureRandom belongs in Person's constructor.

grounded: .claude/agents/json-persistence.md, lib/person_repo.rb:4, lib/person.rb … · 🤖 developerz.ai review — automated, what is this?

- Keep `PersonRepo` a nested class of `Person` — the spec resolves it as `PersonRepo` via spec_helper.
- Store flat hashes (id/full_name/age), not marshalled objects, so the file stays human-readable JSON.
- Prove with `bundle exec rspec` and inspect `tmp/persons.json` after `ruby app.rb`.
47 changes: 47 additions & 0 deletions .claude/commands/feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
description: Take one change in tesote/coding-challenge-quick from idea to merged — explore, build, prove it with bin/check, open one pull request, watch it land. Use for feature, implement, build it, ship this, fix and merge.
argument-hint: <what you want built or fixed>
allowed-tools: Read, Write, Edit, Glob, Grep, Bash, Task
---

# /feature — idea to merged in tesote/coding-challenge-quick

> Workflow command — established by dz-runner setup mode. Correct it in place;
> setup never overwrites a command that exists.

**Done means MERGED.** A green local gate is not done, and an open pull request is not
done. Report what you verified, never what you assume happened.

## Goal

$ARGUMENTS

## Steps

1. Restate the goal in one line. If it names a URL or an issue, read it first.
2. **Distrust the paperwork.** Check any plan, status file or design doc against the code
and `git log` before working from it — trackers rot in both directions. Say plainly
which claims you falsified, and fix the doc in the same change.
3. Explore read-only, in parallel, into a ranked worklist of PR-sized batches.
4. Build primitive-first: one reusable primitive with its first real caller. No
abstraction before a consumer.
5. **Prove it.** `bin/setup` after any dependency change, then `bin/check`, which here is
`bundle exec rspec`.
Red is not a pull request: fix the cause, never silence the gate. Add the failing test
first — a green run that never went red proves nothing.
6. **One pull request in flight, start to finish.** Open it, watch it to merged, run
`git fetch`, and only then start the next. Each merge rebases the base under the
other, and green-when-opened is not green-to-merge.
7. Re-check the original symptom after the merge, and leave the issues and docs true.

## Fan-out rules — restate these to every agent you spawn

- **One checkout. No git worktrees.** Work would land in a directory nobody is looking at,
and each tree costs its own install and its own test database. Disjoint file sets are a
scheduling problem you can see; isolation is one you cannot.
- **Exclusive file sets.** Two agents never write one file, and a rename or a signature
change pulls every caller into the same set.
- **No git in a spawned agent** — no add, commit, branch, stash or push. You own git, and
you touch it only once every agent has returned.
- **Scope each agent to the files it edited.** The repo-wide gate is yours, run once, at
the end.
40 changes: 40 additions & 0 deletions .claude/commands/planx.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
description: Write a self-contained implementation plan under docs/plans/ for another agent to execute. Use for plan, planx, design the work, break this down.
argument-hint: <what you want planned>
allowed-tools: Read, Glob, Grep, Bash, Write
---

# /planx — plan a piece of work in tesote/coding-challenge-quick

> Workflow command — established by dz-runner setup mode. Correct it in place;
> setup never overwrites a command that exists.

**Plan only.** No implementation, no edits outside the plan directory. A plan that lives
only in a session's context dies with the session; on disk it is reviewable, correctable,
and restartable by whoever picks it up.

## Goal

$ARGUMENTS

## Steps

1. Resolve the directory: `date +%Y %m %d`, then the highest existing `1NN-*` under
`docs/plans/<YYYY>/<MM>/<DD>/` plus 1, else `101`. Slug kebab-case, 5 words max.
2. Explore read-only first — find the patterns to follow and the files to change.
3. Write `overview.md`: goal (1-2 sentences), context (only the facts the executor needs,
as `path:line`), the slice files in execution order, done-when, risks.
4. Write one `<NN>-<aspect>.md` per separable AREA OF WORK — `01-data-model.md`,
`02-api.md`, `03-frontend.md`. Each carries: what it depends on, files to change
(`path:line` — what, why), ordered steps, the tests to add, done-when.
5. Write `status.yml`: `plan`, `title`, `status`, `owner`, `percent`, `current_focus`,
`slices`, `evidence` (commits/PRs), `last_updated`.

## Rules

- **Reference, never restate.** Cite `path:line`; pasted code is stale the day it is pasted.
- **Self-contained.** The executor reads `overview.md`, its own slice, and what those cite.
- **Split by area of work, never by chapter.** A slice boundary is the file-set boundary the
build fans out on, and that file set is one pull request.
- **`status.yml` is the only tracker.** No checkboxes in a `.md` — two trackers disagree.
- **Skip the plan for a one-file fix.** Writing it costs more than the change.
41 changes: 41 additions & 0 deletions .claude/skills/verify-change/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
description: Prove a change in tesote/coding-challenge-quick before committing or opening a pull request — the repo's own install, run and check commands. Use before every commit.
---

# Verify a change in tesote/coding-challenge-quick

> House skill — established by dz-runner setup mode from this repo’s own
> detected commands. Correct it in place; setup never overwrites a skill that exists.

## The one gate

`bin/check` is the gate. CI runs it and the pre-commit hook runs it, so a change that

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor · docs The skill asserts bin/check is the gate 'CI runs and the pre-commit hook runs, so a change that passes it locally passes everywhere', yet the head's own CI 'check' runs failed and the local run exited 127 because bundle was unavailable — the claimed guarantee does not hold for the gate this PR installs.

grounded: .claude/skills/verify-change/SKILL.md · 🤖 developerz.ai review — automated, what is this?

passes it locally passes everywhere.

| Step | Command | What it is |
|------|---------|------------|
| install | `bin/setup` | bundle install |
| run | `bin/dev` | ruby app.rb |
| prove | `bin/check` | bundle exec rspec |

## Rules

- Run every command from the repo root — the scripts `cd` there themselves.
- `bin/check` red is not a pull request. Fix the cause, never silence the gate.

## Exit codes `bin/check` must use

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor · docs SKILL.md mandates bin/check exit 75 for unmet environment preconditions, but bin/check has no precondition guard and delegates every failure to bundle exec rspec's exit code. Add the exit-75 guard to bin/setup/bin/check (e.g. command -v bundle or bundle check, else exit 75).

grounded: .claude/skills/verify-change/SKILL.md · 🤖 developerz.ai review — automated, what is this?


A coding box runs this gate before it commits, and it has to tell a FAILING change
from a gate it could not run — otherwise correct work is thrown away as if it were
red. Exit 1 cannot carry that difference, so one code is reserved:

| Exit | Means | What the platform does |
|------|-------|------------------------|
| 0 | the change passes | commit it |
| 75 | a resource the gate NEEDS is unreachable (a database, a service, a credential) — it refused to grade | refuse the commit, and blame the environment, never the change |
| any other non-zero | the gate ran and the change is red | refuse the commit, and blame the change |

- Guard preconditions FIRST and `exit 75` when one is unmet. `exit 1` there tells the
platform your change is broken when it is your environment that is.
- Changed a dependency? Re-run `bin/setup` before `bin/check`, or you are proving a stale tree.
- Add the test that fails first, then the fix — a green run that never went red proves nothing.
5 changes: 5 additions & 0 deletions .codegraph/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# CodeGraph data files — local to each machine, not for committing.
# Ignore everything in .codegraph/ except this file itself, so transient
# files (the database, daemon.pid, sockets, logs) never show up in git.
*
!.gitignore
62 changes: 62 additions & 0 deletions .dz/maintainer/maintainer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# .dz/maintainer/maintainer.yml — how the developerz.ai maintainer agent may act on tesote/coding-challenge-quick.
# Proposed by dz-runner setup mode; MERGING this pull request is the opt-in.
#
# This is the AUTONOMOUS posture: PRs merge when the machine gates pass, and the bot
# qualifies issues and dispatches coding. Releases follow the `release:` block below.
# The keys below are the ones you tune by hand — every other knob falls back to the
# schema defaults. Full reference: https://developerz.ai/docs/maintainer-yml
version: 1

# Services this repo's own verify gate needs running before it can grade a diff.
# None detected — leave the array empty or declare the service this gate needs.
services: []

# handoff: coding dispatches to the developerz fleet (BYOVM). `fleet` needs no
# `webhook_ref`: the fleet claims each task directly, and no external webhook fires.
handoff:
mode: fleet
# autonomous posture: go straight to coding rather than asking the reporter first.
ask_reporter_first: false

# pr:
# - `auto_merge: true` must be written out: the schema default does not count as
# opting in, and without this line the free and open-source tiers keep
# auto-merge off.
# - `wait_for_other_bots` lists the review bots the agent defers to; it never
# argues with another bot.
# - `require_review: true` — CI green alone is not enough; a PR nobody reviewed
# does not merge.
pr:
auto_merge: true
wait_for_other_bots: [coderabbit, copilot]
require_review: true
large_threshold_lines: 500

# release: derived from the detected mechanism. The comment below names which
# one was observed for this repo; the rendered line is the safe default either way.
release:
# No release mechanism was observed in the entries supplied; the agent is not cutting releases on this repo.
manager: none
channels: []

# review: the developerz.ai reviewer, alongside any review bot already installed.
# `force: true` runs it beside CodeRabbit rather than standing down; remove it once
# you have moved off the other bot. `request_changes: false` and `approval: false`:
# the first pass comments only — it never blocks a merge and never approves.
review:
enabled: true
force: true
depth: inline
request_changes: false
approval: false

# triage: ask reporters for repro before dispatching coding — keeps the coding
# queue honest about which issues are dispatch-ready.
triage:
ask_for_repro: true

# escalate: the schema defaults already cover these; stated so you can see what
# stays with a human.
escalate:
always: [hostile_tone, direct_mention]
ask_before_acting: [breaking_change, major_dep_bump, first_time_contributor, large_pr]
29 changes: 29 additions & 0 deletions .dz/maintainer/reviewer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Reviewer instructions — tesote/coding-challenge-quick

> Read by the developerz.ai reviewer at EVERY review of this repository, at the reviewed
> commit, as this repo's own layer of the reviewer's prompt — established by dz-runner setup mode.
> It refines the platform rules (a finding is cited or withheld; the bot always discloses)
> and never overrides them. Edit freely; keep it under 12,000 characters — past that it is cut.

## Stack

Ruby + Bundler + RSpec. The gate is `bin/check` (`bundle exec rspec`): a change that does not pass it is not proven, whatever its description says.

## Review conventions
- Hold every change to the README's requirements: `Person` constructor (first name, last name, age), unique uuid `id`, `full_name`, `save` via `PersonRepo`.
- Verify data is written to `tmp/persons.json` in the documented shape and survives a reload — read the file, don't trust the spec alone.
- Require `# frozen_string_literal: true` at the top of every Ruby file.
- Expect `expect` syntax in specs (spec_helper disables monkey-patching and old `should`).
- Implementation belongs in `lib/person.rb` and `lib/person_repo.rb`; `app.rb` stays the demo entry point.

## Gates that matter
- `bundle exec rspec` exits 0 — all specs green (they fail until the challenge is implemented; that is the baseline, not a broken gate).
- `ruby app.rb` runs to completion and writes `tmp/persons.json`.
- Person ids are UUIDs and identical before save and after reload.
- No new dependencies: Gemfile is rspec-only and that is intentional.

## Never flag
- The intentionally empty/stub bodies the challenge ships (`PersonRepo#save`, the `# ...` markers, the skeleton specs).
- Missing linter, typecheck, CI config, or Rakefile — none exists in this repo by design.
- The `RACK_ENV` line in spec_helper (unused leftover, harmless) and the `vendor/` cache directory.
- One-file-per-class layout and absence of namespaces beyond `Person::PersonRepo`.
76 changes: 76 additions & 0 deletions .dz/onboarding/scorecard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# AI-first scorecard

> Written by the developerz.ai maintainer agent — established by dz-runner setup mode. Each onboarding run rewrites this file whole; the latest run wins, and the same card is stored on the platform.

- Run: `run_2ecbddb5a7ab4d5c9e4bcb006d489a18`
- Computed: 2026-09-18T14:05:21.897Z
- Proof: **unprovable** — `bin/check` did not run green at head on this box. Nothing in the repository’s own code was changed to force it; the excerpt below is the record.
- Score: 9 of 15 items ok

## `policy` — ok

- .dz/maintainer/maintainer.yml established
- .dz/maintainer/reviewer.md established

## `brain` — ok

- CLAUDE.md established

## `roster` — ok

- .claude/agents/json-persistence.md established

## `skills` — ok

- .claude/skills/verify-change/SKILL.md established

## `scripts` — unprovable

- bin/setup established
- bin/dev established
- bin/check established
- ./bin/setup at head: not_runnable, exit 127 (0.0s)

## `wiring` — ok

- .mcp.json established

## `commands` — ok

- .claude/commands/planx.md established
- .claude/commands/feature.md established

## `access` — gap

- asked for 0 credentials

## `layout` — gap

- migration to the house layout filed as tasks
- apps/coding-challenge-quick: 7 move(s) planned as one task

## `smoke_test` — unprovable

- spec/person_repo_spec.rb in the repository
- ./bin/check at head: not_runnable, exit 127 (0.0s)

## `env_example` — gap

- nothing recorded

## `agents_md` — ok

- AGENTS.md established

## `per_workspace_brains` — ok

- single-package repository: 0 workspaces
- CLAUDE.md established

## `docs_readme` — ok

- docs/README.md established

## `gate_proved` — unprovable

- ./bin/check at head: not_runnable, exit 127 (0.0s)
7 changes: 7 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash
# pre-commit gate — established by dz-runner setup mode. Runs the SAME
# `bin/check` CI runs, so a commit that would fail CI fails here first.
# ACTIVATE IT (once, per clone): git config core.hooksPath .githooks
set -euo pipefail
cd "$(dirname "$0")/.."
exec bin/check
15 changes: 15 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# CI green-gate — established by dz-runner setup mode.
# Runs the SAME `bin/check` a coding agent runs locally, so a green local run
# cannot land red here. Adjust the toolchain step below if the default runner
# image does not carry yours (e.g. actions/setup-node, oven-sh/setup-bun).
name: check

on: [push, pull_request]

jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: bin/setup

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

major · bug The workflow runs bin/setup with no Ruby/Bundler toolchain step, and both head CI runs failed (exit 127, bundle not found) — ubuntu-latest's default Ruby lacks the setup this script assumes. Add ruby/setup-ruby with bundler-cache before bin/check so the declared green gate can actually pass.

Suggested change
- run: bin/setup
- uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- run: bin/setup
- run: bin/check

grounded: .github/workflows/ci.yml · 🤖 developerz.ai review — automated, what is this?

- run: bin/check
Comment on lines +11 to +15

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

major · maintainability CI relies on whatever Ruby/bundler the ubuntu-latest image happens to carry — no setup-ruby step and no version pin — so green runs can silently break on runner-image updates, and the PR's own proof shows bundle: command not found on one box. Add actions/setup-ruby (or ruby/setup-ruby) with a pinned Ruby version before bin/setup.

grounded: .github/workflows/ci.yml, lib/person_repo.rb, lib/person.rb · 🤖 developerz.ai review — automated, what is this?

35 changes: 35 additions & 0 deletions .mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"mcpServers": {
"sentry-mcp": {
"type": "stdio",
"command": "bunx",

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor · security bunx @sentry/mcp-server resolves the package to the latest version at every agent launch with no lockfile or version pin, so a compromised upstream release is executed on the operator's machine with the SENTRY_ACCESS_TOKEN in its environment. Pin an exact version (e.g. bunx @sentry/mcp-server@<version> or a bun lockfile entry).

grounded: lib/person_repo.rb, lib/person.rb · 🤖 developerz.ai review — automated, what is this?

"args": [
"@sentry/mcp-server"
],
"env": {
"SENTRY_ACCESS_TOKEN": "${SENTRY_ACCESS_TOKEN}",
"SENTRY_HOST": "${SENTRY_HOST}"
}
},
"codegraph": {
"type": "stdio",
"command": "codegraph",
"args": [
"serve",
"--mcp"
],
"env": {
"DO_NOT_TRACK": "1",
"CODEGRAPH_TELEMETRY": "0",
"CODEGRAPH_NO_UPDATE_CHECK": "1"
}
},
"developerz": {
"type": "http",
"url": "https://mcp.developerz.ai/v1/mcp",
"headers": {
"Authorization": "Bearer ${DEVELOPERZ_API_KEY}"
}
}
}
}
Loading
Loading