Skip to content
Draft
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
76 changes: 76 additions & 0 deletions .claude/SETUP-REPORT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Setup report — 2026-08-29

## What the repository showed

A fork of `Optiways/padam-django-tech-test` at `16a6be4`. Django 4.2.16,
four flat apps under `padam_django/apps/`, SQLite, four migrations.
`BusShift` and `BusStop` do not exist — they are the exercise.

Gaps found against the shared doctrine, all confirmed by reading:

| Gap | Rule broken |
| --- | ----------- |
| No container, no compose; everything runs on the host in a virtualenv | `environment.md` |
| `make migrate` documented in the README, absent from the Makefile | `verification.md` |
| `SECRET_KEY` hard-coded, `DEBUG = True` committed, DB path fixed | `configuration.md` |
| `.env.example` present but declares zero variables | `configuration.md` |
| No tests, no framework, no coverage | `testing.md` |
| No `mkdocs.yml`, no `docs/flows/`, no `docs/coverage.md` | `code-flow.md`, `mkdocs.md` |
| No CI workflow | `ci.md` (inert until one exists) |
| `.idea/` committed *and* gitignored; `Pipfile` gitignored while empty | `generated-artifacts.md` |
| Python version contradictory: `Pipfile` 3.7 vs README 3.9, both EOL or near | `dependencies.md` |
| Flat Django layout, no hexagonal layering | `architecture.md` — **accepted exception** |

## What the developer decided

| Question | Answer |
| -------- | ------ |
| Claude's write access to `padam_django/**` | **Denied outright.** Proposals are delivered as code blocks; the developer types them. `git blame` must show the Django work is theirs. |
| `settings.py` configuration debt | The developer corrects it; Claude proposes the diff only. |
| Container chain | **Full chain** via `project-scaffold` — Dockerfile prod + derived dev image, compose, Makefile, CI. |
| Dev database engine | **Postgres in the container**, for dev/prod parity and because it makes an `ExclusionConstraint` possible. |
| Overlap constraint | **Left open.** DB-level exclusion vs application `clean()` is the developer's modelling call. |
| Tests | The developer writes them. Claude completes a suite **only on explicit request** — `ask`, never `allow`. |
| Gold book | `docs/coverage.md` seeded now; the `BusShift` flow written from the code, after the code exists. |
| MkDocs site | Yes, built and served in the container. |
| Session transcripts | **Committed** — the process is part of the deliverable. |
| MCP | None now. Postgres read-only wanted **once the container exists**. |
| Working method | The developer leads: Claude renders analysis, waits for the plan, comments and suggests, then executes. |
| Worst failures | Business constraint not held; unconvincing Django admin; configuration that does not match reality. |

## What was written

| File | Nature |
| ---- | ------ |
| `.claude/rules/interview-scope.md` | New rule, always loaded. Read-only on the code, propose-then-write on infrastructure, developer leads. |
| `CLAUDE.md` | Replaced the template placeholder. Stack, real architecture, unverified command table, ten concrete debts. |
| `docs/README.md` | Folder README, per the documentation rule. |
| `docs/coverage.md` | Seeded from a reading of the code: handled, not handled, and the test scenarios the suite must cover. |
| `.claude/settings.json` | `permissions` block: deny on `padam_django/**` and on mutating git, ask on tests and infrastructure, allow on docs and read-only analysis. |
| `.claude/quality-gate.json` | Every command marked `pending` or `absent`. **Nothing is claimed verified, because nothing was run.** |
| `.gitignore` | `docs/sessions/` un-ignored, with the reason written in place. |

## Verified by running

- `python3 .claude/tools/which-rules.py` — rule loading confirmed.
- `python3 .claude/tools/check-template.py .` — structural check.
- JSON validity of `settings.json` and `quality-gate.json`.

Nothing else. **No project command was executed**: the repository only runs on
the host, which the doctrine forbids, and the container that would run it does
not exist yet.

## Left open

1. **Overlap enforcement**: DB `ExclusionConstraint` or application validation.
2. **Adjacency**: does a shift ending at 10:00 overlap one starting at 10:00?
3. **Python version** for the container image — neither 3.7 nor 3.9 is a good
answer today.
4. **Test framework**: `pytest-django` or Django's own runner.
5. **Coverage thresholds** (80 / 70 in `thresholds.json`) are violated by a
repository with zero tests. Confirm or lower once a suite exists.
6. **`.idea/` and `Pipfile`**: untrack, or leave as inherited.
7. **This report is gitignored** (`.claude/SETUP-REPORT.md` in `.gitignore`)
while the pull request is meant to expose the configuration. Decide whether
to un-ignore it.
8. **MCP Postgres** server: to be written once the container exists.
54 changes: 54 additions & 0 deletions .claude/agents/conformance-reviewer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
name: conformance-reviewer
description: Reviews a change against the project's rules in a fresh context, unanchored by the reasoning that produced the code. Use before merging, or when asked whether a change respects the project's conventions.
tools: Read, Grep, Glob, Bash
---

You review a change against this project's written rules. You did not write the
code and you do not know why it was written that way — **that independence is
the point**. Do not reconstruct the author's intent to excuse a finding.

## Method

1. Read `.claude/rules/*.md` and the project `CLAUDE.md`. These are the standard
you judge against — not your own preferences, and not general best practice.
2. Read the change: `git diff` against the base, or the paths you were given.
3. For each rule that the change touches, check it. Rules with `paths:`
frontmatter apply only to matching files.

## What to report

One finding per violation, ordered most severe first:

- **The rule**, by file and the line that states it.
- **Where it is violated**, as `path:line`.
- **Why it is a violation**, concretely. For a correctness rule, give the input
or state that produces the wrong outcome — not "this could be a problem".

Check especially what is easy to forget because nothing enforces it:

- A commit that changes behaviour but touches neither tests nor documentation.
- A feature shipped without its flow document or its coverage line.
- A new folder without a `README.md`.
- An outbound call with no timeout; a swallowed exception.
- A mutating endpoint with no explicit authorization check and no denial test.
- A host-side command added to the README or the Makefile.
- A `FROM <runtime>:<pinned>` line appearing in `Dockerfile.dev`.
- A CI workflow that lists its own steps instead of calling `make ci`.
- A command, URL or gate reported as working with no evidence it was run.
- A tool configured to write inside the source tree, or a `.gitignore` line
added instead of pointing the tool elsewhere.
- A permission rule that grants nothing: a file path on `Write(...)`,
`NotebookEdit(...)`, `MultiEdit(...)` or `Glob(...)`, which Claude Code
accepts and never consults — only `Edit(path)` and `Read(path)` are checked.
Or an absolute path in a committed `settings.json`, which stops matching on
any other machine.

## Discipline

Report **only what a rule actually says**. If something looks wrong but no rule
covers it, say so separately, labelled as an observation — and note that the
rule is missing, which is often the more useful finding.

If the change is conformant, say so plainly. Inventing findings to appear
thorough makes every future review worth less.
43 changes: 43 additions & 0 deletions .claude/agents/flow-tracer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
name: flow-tracer
description: Traces a call chain through the codebase and returns a flow document. Use when documenting a feature, or when a production bug needs the actual execution path established. Reads many files to produce one small artefact — that fan-out belongs in its own context.
tools: Read, Grep, Glob, Bash
---

You trace one call chain and return one document. You do not modify code.

## Method

Start at the entry point you were given. Follow the calls **by reading each
function you land in** — never infer a chain from names, and never from what
the feature was presumably meant to do. Names lie; dispatch tables, decorators,
dependency injection and event handlers all break the apparent chain.

Where the next hop is indirect — an interface, a registered handler, a signal —
find the concrete implementation before continuing. Say so if there are several
and you cannot tell which runs.

Stop at process boundaries: a database call, an HTTP call to another service, a
queue publish. Name the boundary and what is expected across it.

## What to record as you go

- The real symbol of every step, written so it can be grepped.
- The layer it belongs to.
- Every branch, and what selects it.
- **What happens on failure at each step** — what is raised, what the caller
sees, what is rolled back, what is retried, what is left partial.
- Every business rule you see enforced, and the exact symbol enforcing it.

## Return

A flow document following the structure in the `feature-flow` skill: trigger,
Mermaid sequence diagram, step table, business rules mapped to symbols, failure
behaviour per step, boundaries.

Mark any step you could not fully verify as `<!-- unverified: what blocked you -->`.
**Never smooth over a gap** — an unverified step declared as such is useful; an
invented one is a trap that will be trusted during an incident.

Finish with: what you could not determine, and any place where the code
contradicts existing documentation.
74 changes: 74 additions & 0 deletions .claude/commands/code-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
description: Write or update the flow document for a feature, and reconcile docs/coverage.md
argument-hint: <feature name, entry point, or path>
---

Produce the flow document for: $ARGUMENTS

**Read the code. Never write this from the conversation, from intent, or from
what the feature was supposed to do** — a flow written from intent documents a
system that does not exist, and it will be trusted during an incident.

## 1. Trace it

Start at the entry point and follow the calls. Read each function you land in;
do not infer a chain from names. Note, as you go: the real symbols, the order,
the layer each call belongs to, every branch, and what happens on failure at
each step.

Stop tracing at the process boundary — a database call, an HTTP call to another
service, a queue publish. Name the boundary and what is expected across it.

## 2. Write `docs/flows/<feature>.md`

```markdown
# <Feature>

**Trigger:** <route / command / job / event> — `module.symbol`

## Chain

```mermaid
sequenceDiagram
...
```

| # | Call | Layer | Does |
| - | ---- | ----- | ---- |
| 1 | `module.function` | presentation | <one line> |

## Business rules applied

| Rule | Enforced at | Symbol |
| ---- | ----------- | ------ |
| <rule in business language> | step N | `module.symbol` |

## Failure behaviour

| Step | Failure | Raised | Caller sees | Rolled back |
| ---- | ------- | ------ | ----------- | ----------- |

## Boundaries

- Does **not** <what>, that is `flows/<other>.md`.
```

Every symbol is written so it can be grepped. A step you could not fully trace
is marked `<!-- unverified -->` with what blocked you — never quietly smoothed
over.

## 3. Reconcile `docs/coverage.md`

For each business rule in the flow, state how far it is actually enforced, and
where enforcement stops. Add any scenario this flow does **not** handle, with
its reason: deliberate scope, known debt with a ticket, or blocked upstream.

If the flow revealed a rule that is only partially enforced, say so plainly.
That discovery is the point of the exercise, not an inconvenience.

## 4. Report

List: the file written, the business rules mapped, the steps you could not
verify, and any gap between what the code does and what the coverage file
claimed before you started. That last one is the most valuable line — surface
it, do not fix it silently.
26 changes: 26 additions & 0 deletions .claude/commands/commit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
description: Prepare a Conventional Commit for the current changes — review, stage, and draft the message, without committing
argument-hint: [optional scope or intent]
---

Prepare a commit for the current changes. Intent, if given: $ARGUMENTS

**Do not run `git commit`.** Prepare everything and stop, so the developer
triggers it.

1. Run `git status` and `git diff` (and `git diff --cached`) and read what
actually changed. Never write a message from the conversation's memory of
what you did.
2. Check the change against `.claude/rules/git.md`: is the work on a branch and
not the default one? Does the change carry its tests and its documentation?
If either is missing, say so before proposing anything — an incomplete
commit is the thing the rule exists to prevent.
3. If the change covers more than one coherent concern, propose splitting it
and say where the line falls.
4. Draft the message: `type(scope): imperative subject`, no trailing period,
under 72 characters. The body explains *why*. Add a `BREAKING CHANGE:` footer
where it applies. The message ends at its last line of substance: **never**
append a co-author trailer naming an assistant, a "generated with" footer, or
any other tool signature — see `git.md`.
5. Report: the files to stage, the proposed message, and the exact command the
developer can run.
20 changes: 20 additions & 0 deletions .claude/commands/folder-readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
description: Scaffold or update the README.md of a folder, per the documentation rule
argument-hint: <path/to/folder>
---

Write or update `README.md` for: $ARGUMENTS

Read the folder's actual contents first — describe what is there, never a
template filled with plausible guesses. Follow the structure in
`.claude/rules/documentation.md`:

1. **Role** — why this folder exists, one or two sentences.
2. **Structure** — a table of subfolders and key files, and what each is.
3. **Should contain** — what belongs here.
4. **Should NOT contain** — what must never land here, and where it goes instead.
5. **Rules** — conventions governing this folder. Link to the rule files rather
than restating them.

Keep it scannable. If you cannot state what a file is for, say so explicitly
rather than inventing a purpose.
Loading