Skip to content
Back to skills

Saas Create Control Manifest

BSecurity

Builds a short list of must-do and never-do coding rules per system from accepted ADRs. Use when the user wants programmer rules or a quick reference sheet from the ADRs, or needs it regenerated after ADR changes.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
businessgobashnextjsrailsapidatabaseperformancedocumentation

Works with

  • cli
  • api

Security analysis

B88/100
  • criticalImpersonates system messages to override safety constraints

Pro shows the line behind each finding and how to fix it

Scanned November 7, 2026

npx -y skills add Basinfy/Basinfy-SaaS-Studio --skill saas-create-control-manifest --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Saas Create Control Manifest?

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

Security grade badge for Saas Create Control Manifest
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/basinfy-saas-create-control-manifest/badge)](https://www.skillsdirectory.com/skills/basinfy-saas-create-control-manifest)

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: saas-create-control-manifest
description: "Builds a short list of must-do and never-do coding rules per system from accepted ADRs. Use when the user wants programmer rules or a quick reference sheet from the ADRs, or needs it regenerated after ADR changes."
argument-hint: "[update — regenerate from current ADRs] [--review full|lean|solo]"
user-invocable: true
allowed-tools: Read, Glob, Grep, Write, Agent, AskUserQuestion, Bash(bash "*/.claude/skills/saas-create-control-manifest/../../hooks/yaml-helper.sh" resolve_config *), Bash(bash .claude/scripts/adr-status.sh*), Bash(bash .claude/scripts/md-section.sh *)
model: sonnet
---

!`bash "${CLAUDE_SKILL_DIR}/../../hooks/yaml-helper.sh" resolve_config --keys locale,review_mode,review_gate,automation`

Resolved above — use as-is; `--review` overrides `review_mode` for this run. No
block → defaults in `.claude/docs/config-resolution.md`.

Ask with the question tool. Without one, list the options numbered and end your turn
to wait. A skipped or dismissed question is not an answer: ask again in plain text.

# Create Control Manifest

> **Interaction Localization Rule**:
> When `locale: pt-BR` (or user speaks Portuguese), ALL questions (`AskUserQuestion` / `ask_question`), confirmation prompts, and selectable options MUST be translated and presented in **Brazilian Portuguese (PT-BR)**.
> Any English question text or options in this skill are illustrative examples — NEVER display English questions or options to a Portuguese developer.
> Internal reasoning, code synthesis, tests, and documentation files MUST remain in English.

The control manifest is a flat rules sheet for programmers: what to do and what
never to do, by architectural layer, taken from the Accepted ADRs, the project's
technical preferences and the stack reference docs. The ADRs say *why*; the
manifest says *what*.

**Writes:** `docs/architecture/control-manifest.md`, after the user's yes.
**When:** after `/saas-architecture-review` passes and the ADRs are Accepted. Run it
again whenever an ADR is accepted or revised.

Asks follow `.claude/docs/automation-modes.md` (collaborative always asks, guided
asks on major choices, autonomous logs and goes on; `automation_always_ask`
categories always ask).

## Phase 1: Load the inputs

### ADRs

`bash .claude/scripts/adr-status.sh` reads every `docs/architecture/adr-*.md` in one
pass: the counts first (`adrs`, then `accepted`, `proposed`, `deprecated`,
`superseded`, `unfilled`, `other`, `no_status`), then one row per ADR with its
status and layer. Establish the denominator first: decide from the counts, before
reading any ADR:

| Counts | Meaning | Action |
|---|---|---|
| `adrs 0` | No ADRs. | "No ADRs found — run `/saas-architecture-decision` before building a control manifest." Stop. |
| `accepted` ≥ 1 | Normal. | The Accepted rows are the set **A**. Name every other ADR, with its status, in the Phase 4 preview: the user approves a manifest knowing what it leaves out. |
| `accepted 0`, some with a status | No Accepted ADRs. | "[N] ADRs found, none Accepted. A manifest built from Proposed ADRs would encode decisions that may still change." Ask whether to go on with the Proposed ones or stop. **Never write an empty manifest silently.** |
| every ADR `no_status` | **Malformed ADRs, not an empty Accepted set.** | "[N] ADRs found, none has a `## Status` section, so acceptance cannot be told. Run `/saas-architecture-decision retrofit [file]` on each." Stop. Never treat them as Accepted. |

Each stop above ends with `Verdict: BLOCKED — [the reason]`. Note the number and
title of every ADR a rule comes from.

### Project config

- `naming.*` and `performance.*` from `project.yaml`; for any key absent or empty,
  `.claude/docs/technical-preferences.md`.
- Approved libraries and forbidden patterns from
  `.claude/docs/technical-preferences.md` (not migrated to `project.yaml`).

### Stack reference

- `docs/engine-reference/[engine]/VERSION.md` for the engine and version.
- `docs/engine-reference/[engine]/deprecated-apis.md`: these become forbidden APIs.
- `docs/engine-reference/[engine]/current-best-practices.md`, when it exists.

### What exists already

`docs/architecture/control-manifest.md` present: this run regenerates it; read it
before the Phase 5 write, which replaces it. `production/epics/*/EPIC.md` present:
epics exist. Phase 6 picks its next step from both.

Report: "Loaded [A] Accepted ADRs of [N], engine: [name + version]."

## Phase 2: Extract the rules from each ADR

For each ADR in **A**, read only four sections, never the whole file:

```
bash .claude/scripts/md-section.sh extract docs/architecture/[adr-file].md "Decision"
```

and the same for `Alternatives Considered`, `Performance Implications` and `Engine
Compatibility`. Context, Consequences, Migration Plan and Validation Criteria say why
a decision was made; the manifest records what to do. A section an ADR lacks: note
it for that ADR and go on. A section missing from **every** ADR in A: report "No
Accepted ADR has a `[section]` section — the manifest's [category] rules will be
empty. Verify this is intended." Read beyond the four only when a section points
outside itself ("subject to the constraints in Context"), and then that one section.

From each ADR:

- **Required patterns** (Decision): every "must", "should", "required to",
  "always", and every pattern or approach it mandates, including any `### Implementation
  Guidelines` inside it. Never look for that sub-heading alone: many ADRs state
  their mandates directly under Decision, and a scan for the sub-heading alone
  yields an empty section.
- **Forbidden approaches** (Alternatives Considered): every rejected alternative,
  with why it was rejected as the rule ("never use X because Y"), and any named
  anti-pattern.
- **Performance guardrails** (Performance Implications): budgets ("max N ms per
  frame for this system") and memory limits.
- **Engine API constraints** (Engine Compatibility): post-cutoff APIs that need
  verifying, behaviour that differs from what a model would assume, fields or
  methods that changed in the pinned version.

**Layer.** Each rule goes under the layer of the system it governs, the ADR's
`layer` column where it has one:

- **Foundation:** auth & session management, database connection & RLS, queue worker runtime, application bootstrap
- **Core:** core business workflow logic, tenant isolation, billing & subscription entitlements, primary domain models
- **Feature:** secondary workflows, integrations, webhook handlers, notification services, AI services
- **Presentation:** UI components, responsive layout, form validation, theme tokens, client-side state

An ADR that spans layers puts its rule in each one.

## Phase 3: Add the global rules

Rules for every layer, each with its source (the `project.yaml` key,
`technical-preferences.md`, or the engine-reference file), as a layer rule has:

- **Naming** from `naming.*`: classes, variables, signals and events, files,
  constants.
- **Performance budgets** from `performance.*`: target LCP, target FID/INP,
  target CLS, max initial bundle size, API p95 latency.
- **Forbidden APIs** from stack reference documentation, **only those that apply to what this
  project builds.** Never copy deprecated lists blindly: scope each rule to the relevant
  package/framework (e.g. Next.js App Router vs Pages Router deprecated methods). When you cannot
  tell whether an entry applies, scope the rule or leave it out and list it as
  unresolved. `/saas-create-stories` reads this file, and rules that do not apply are
  rules nobody reads.
- **Required patterns** from `current-best-practices.md`, when it exists.
- **Forbidden patterns** from `technical-preferences.md`, copied as written.

## Phase 4: Show the summary, then the review

```
## Control Manifest Preview
Engine: [name + version]
ADRs covered: [ADR numbers]
ADRs left out: [ADR-NNNN ([status]), … — every ADR not in A, or "None"]
Rules extracted:
  - Foundation layer: [N] required, [M] forbidden, [P] guardrails
  - Core layer: [N] required, [M] forbidden, [P] guardrails
  - Feature layer: …
  - Presentation layer: …
  - Global: [N] naming conventions, [M] forbidden APIs, [P] approved libraries
Unresolved: [engine entries left out because whether they apply is unclear, or "None"]
```

Ask: "Does this rule summary look complete?" Options: Yes — review and write it /
Add rules — I have more to include / Remove rules — some should be dropped / Stop —
I need to review the ADRs first.

**The technical review.** Read the `review_gate` line above. `skill-gates=skip`
(solo or lean): no agent; note `TD-MANIFEST skipped — [Solo | Lean] mode`.
`skill-gates=run`: hand the review to the `technical-director` agent with gate
**TD-MANIFEST** (`.claude/docs/director-gates/td-control-manifest.md`; the agent reads it
itself). Brief:

- **Objective:** check the extracted rules before they are written.
- **Give it:** the preview above with the full rule list, the ADRs covered, the
  engine version, and the rules taken from technical preferences or the engine
  reference.
- **Check:** every mandatory ADR pattern is captured and stated accurately; the
  forbidden approaches are complete and correctly attributed; no rule lacks a source
  ADR or preference document; the guardrails agree with the ADRs' constraints.
- **Return:** APPROVE, CONCERNS, REJECT, or NOT ASSESSED naming a missing input.
- **Boundaries:** it writes no file.

Act on the verdict:

- **APPROVE:** go to Phase 5.
- **CONCERNS:** ask: "The technical director raised concerns. How do you want to go
  on?" Options: Revise the flagged rules / Accept and go on / Discuss further.
- **REJECT:** write nothing; fix the flagged rules and show the summary again.
- **NOT ASSESSED:** it is not an approval (`.claude/docs/director-gates.md`). Name
  what was missing, then supply it and run the review again; or, when the user
  chooses to go on without it, go to Phase 5 and state `TD-MANIFEST: NOT ASSESSED —
  [input]` in the reply and the final verdict line.

## Phase 5: Write the control manifest

Ask: "May I write the control manifest to `docs/architecture/control-manifest.md`?"
Options: Yes, write it / Show me the full draft first, then ask again / Not yet — I
want more changes. Write only on an explicit yes.

```markdown
# Control Manifest

> **Engine**: [name + version]
> **Last Updated**: [date]
> **Manifest Version**: [date]
> **ADRs Covered**: [ADR-NNNN, ADR-MMMM, ...]
> **Status**: Active — regenerate with `/saas-create-control-manifest update` when ADRs change

`Manifest Version` is the date this manifest was generated. Stories embed it when
they are written, and `/saas-story-readiness` compares a story's version with this one
to find stories written against old rules. It always equals `Last Updated`: the
same date, for different readers.

This manifest is a programmer's quick reference taken from the Accepted ADRs, the
technical preferences and the stack reference docs. For the reason behind a rule,
read its ADR.

---

## Foundation Layer Rules

*Applies to: authentication, database schema, event bus, session management, middleware*

### Required Patterns
- **[rule]** — source: [ADR-NNNN]

### Forbidden Approaches
- **Never [anti-pattern]** — [brief reason] — source: [ADR-NNNN]

### Performance Guardrails
- **[system]**: max p95 [N]ms API latency / TTFB — source: [ADR-NNNN]

---

## Core Layer Rules

*Applies to: core business workflows, domain logic, data models, state machines*

### Required Patterns
...

### Forbidden Approaches
...

### Performance Guardrails
...

---

## Feature Layer Rules

*Applies to: secondary workflows, AI services, integration features*

### Required Patterns
...

### Forbidden Approaches
...

---

## Presentation Layer Rules

*Applies to: UI components, design tokens, client state, forms, layouts*

### Required Patterns
...

### Forbidden Approaches
...

---

## Global Rules (All Layers)

### Naming Conventions
| Element | Convention | Example | Source |
|---------|-----------|---------|--------|
| Classes | [convention] | [example] | [`naming.classes` in project.yaml, or technical-preferences.md] |
| Variables | [convention] | [example] | [`naming.variables` in project.yaml, or technical-preferences.md] |
| Signals/Events | [convention] | [example] | [`naming.signals` in project.yaml, or technical-preferences.md] |
| Files | [convention] | [example] | [`naming.files` in project.yaml, or technical-preferences.md] |
| Constants | [convention] | [example] | [`naming.constants` in project.yaml, or technical-preferences.md] |

### Performance Budgets
| Target | Value | Source |
|--------|-------|--------|
| Target LCP (ms) | [value] | [`performance.target_lcp_ms` in project.yaml] |
| Target FID/INP (ms) | [value] | [`performance.target_fid_ms` in project.yaml] |
| Target CLS | [value] | [`performance.target_cls` in project.yaml] |
| Max Initial Bundle (KB) | [value] | [`performance.max_initial_bundle_kb` in project.yaml] |
| API p95 Latency (ms) | [value] | [`performance.api_p95_latency_ms` in project.yaml] |

### Approved Libraries / Packages
- [library] — approved for [purpose] — source: technical-preferences.md

### Forbidden APIs ([stack version])
These APIs are deprecated or unverified for [stack + version]:
- `[api name]` — deprecated since [version] / unverified post-cutoff
- Source: stack reference documentation

### Cross-Cutting Constraints
- [constraint that applies in every layer] — source: [ADR-NNNN, preference key or architectural standard]
```

## Phase 6: Next steps

- No epics yet: "Run `/saas-create-epics layer: foundation`, then `/saas-create-stories
  [epic-slug]`: stories embed this manifest's rules and version."
- A regeneration: "Updated. Tell the team about the changed rules, above all any
  new Forbidden entries."

Every rule traces to an ADR, a technical preference or an stack reference doc;
none is invented, and none is paraphrased in a way that changes its meaning. End
with `Verdict: COMPLETE — control manifest written` after the write, or `Verdict:
BLOCKED — user declined the write` when declined.

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.