Skip to main content
Welcome. This site supports keyboard navigation and screen readers. Press ? at any time for keyboard shortcuts. Press [ to focus the sidebar, ] to focus the content. High-contrast themes are available via the toolbar.
serard@dev00:~/cv

Requirements-as-Code with AI: A Controlled Delivery Workflow

Humans decide what must be true. AI helps build it. Types constrain the relationships. Verification challenges the result.

Please read Requirements-as-Code - Type It before

Please view Requirements-as-Code - Governance for Governance

AI-assisted delivery needs more than a detailed prompt followed by a green test run. It needs a clear answer to three questions: who defines success, where that definition lives, and what may change when the implementation fails?

This workflow connects a bounded human intention to an acceptance decision supported by evidence. The starting point can be a new need or, in the specification-recovery experiment below, an existing system whose intended behavior needs clarification. AI can help elicit requirements, materialize a typed model, propose verification, write tests, design an implementation, and repair failures. It does not acquire the authority to approve its own requirements or quietly weaken the contract it is supposed to satisfy.

The conceptual and technical foundation is Requirements-as-Code: turn the problem–solution layer into a type system. This companion page develops its AI workflow into twelve explicit stages, with paths for @frenchexdev/requirements in TypeScript and FrenchExDev.Net.Requirements in C#.

The worked example reuses the concept page's Markdown-rendering requirement and acceptance criteria. Its scoping decisions, review exchanges, and failure scenarios below are illustrative, not a report of a live project run. Repository approval controls, evidence collection, and the consumer-side verification plan are integration designs—not claims that either library already ships a turnkey agent-governance platform.

The Contract Is a Type System, Not a Prompt

The contract is not a Markdown document that each model is invited to interpret again. It is a versioned, human-approved model of requirements, features, acceptance criteria, and their verification relationships.

Natural language still matters. A requirement contains a statement, rationale, context, and fit criteria. Types do not erase their ambiguity or prove their business relevance. They give the obligations stable identities, explicit structure, and relationships that compilers and analyzers can check. Humans still approve the meaning; tools reject the particular structural and policy violations they know how to detect.

A useful separation is:

Artifact Authority and purpose
Scoped human intent Defines the goal, constraints, exclusions, and questions to resolve. It is the input to elaboration, not a licence to invent requirements.
Candidate typed model An AI or human proposal. Well-typed does not mean approved.
Approved typed baseline The authoritative requirement contract for the selected delivery slice. Changes require an explicit decision.
Reviewed features, ACs, and verification policy Define how the chosen capability will be evaluated without silently redefining the requirement.
Markdown, diagrams, tracker views, and context bundles Explain or project the model. An edit to a view is a proposed change, not automatic approval.
Tests, implementation, and run artifacts Work products assessed against the approved contract and verification policy.

Typed Specs was the prototype name. Spec-driven development describes a process; Requirements-as-Code supplies a typed representation and enforceable relationships within that process. The workflow uses both ideas without treating them as competing products.

Diagram
AI produces candidates and work products. It is not the authority over the obligation or the evidence used to accept delivery.

An AC declaration is not the production implementation and is not an executed predicate. A test binding is not a passing result. Evidence belongs to a particular baseline, implementation, environment, and run.

Starting from Existing Code and Tests

Experiment in progress. I am exploring how AI-assisted analysis can recover candidate requirements from an implementation and its tests. The intended benefit is to make software knowledge reviewable, identify inconsistencies or verification gaps, and prepare controlled refactoring or redesign. This is a workflow experiment using code inspection and Requirements-as-Code tooling; it is not a shipped automatic specification-recovery engine.

  1. Choose a bounded slice. Identify the behavior, source revision, relevant tests and available documentation. Record the questions that motivated the investigation.
  2. Observe the implementation and tests. Separate behavior visible in source, assertions present in tests and results actually obtained by running them. Keep references to the observations.
  3. Propose the model. Express candidate Requirements (why), Features (what) and Acceptance Criteria (observable obligations). Keep inferred intent, assumptions and conflicting evidence visible.
  4. Relate existing tests. Inspect what each assertion checks and propose bindings to the candidate criteria. Tests may characterize current behavior without establishing that it is desirable.
  5. Review with a human. Decide which behavior to preserve, which candidates to reject or refine, and which changes to require. Record an approved, versioned baseline for the selected slice.
  6. Assess gaps against that baseline. Identify missing or inadequate verification and mismatches between required and observed behavior. A missing binding alone does not establish that a test is missing.
  7. Evolve and verify. Reuse and strengthen appropriate tests, then refactor or redesign within the approved scope. Run the relevant checks and review fresh evidence against the baseline.

Observed behavior is input to a decision. An implementation can contain defects, and tests can encode those defects. Neither an AI reconstruction nor a passing test establishes the original business intent. Human review decides the obligations to adopt before they guide further changes.

Illustrative example: Markdown rendering. The following is a teaching scenario based on this page's rendering example, not a report of a completed recovery experiment or a newly discovered site defect.

Step Illustrative proposal or question
Observations to collect Trace the title from frontmatter to HTML; inspect title assertions and record their sources.
Requirement — why When Markdown declares a title, the published page shall expose it so readers can identify the document.
Feature — what Render document metadata into the published page.
Acceptance criterion The declared title appears in static HTML, including when browser JavaScript is disabled.
Tests to relate Inspect title assertions and no-JavaScript scenarios. Bind only the behavior they actually verify.
Human review Missing title: which fallback? Conflicting heading: which wins? Which behavior must change?
After approval Compare behavior and checks with the approved policy, address gaps, then collect fresh results.

For example, the missing-title question may lead to an approved fallback rule and a corresponding test. That is a proposed policy decision; this example does not claim that the current implementation lacks that behavior or its tests.

The existing TypeScript declaration ↔ JSON spec synchronization translates an already expressed model. Semantic recovery instead proposes meaning from code, tests and context. Once reviewed, that model joins the twelve-stage workflow below: review and freeze the contract, assess verification, evolve the implementation, then evaluate the results. AI proposes, tooling checks, people decide.

The Twelve-Stage Workflow

The workflow contains three loops with different authority boundaries: decide the contract, satisfy the contract, and change the contract. Mixing them allows an implementation problem to become an unnoticed change of goal.

Stage Work Output and exit condition
1. SCOPE Select a bounded problem, actors, constraints, exclusions, and owners. A delivery slice small enough to review and verify.
2. INTENT Express the expected outcome in scoped natural language. A shared intention, with unresolved questions visible.
3. ELICIT Ask AI to propose requirements across relevant abstraction levels and concerns. Candidate obligations, rationale, assumptions, and questions.
4. MATERIALIZE Express candidates as the project's typed Requirement intermediate representation. Reviewable C# or TypeScript declarations, checked for supported structural rules.
5. REVIEW Humans mark candidates green, red, or refine. Explicit decisions on specific candidates and versions.
6. FREEZE Record the approved requirement slice. A versioned requirement baseline, not an immutable project plan.
7. DERIVE Propose and review Features, ACs, and verification obligations. A versioned verification plan linked to the baseline.
8. VERIFY-FIRST Write tests, properties, contracts, and inspection procedures before allowing implementation to define the expected result. Reviewed checks and, where applicable, an observed failure against missing or incorrect behaviour.
9. SYNTHESIZE Design and implement within the approved scope. A proposed solution with explicit dependencies and decisions.
10. PROVE Run compiler checks, analyzers, tests, coverage, mutation, and configured gates. Applicable evidence—or explicit failures and gaps.
11. ITERATE Repair implementation or verification defects without changing the approved obligation. Another bounded attempt against the same baseline.
12. CHANGE Escalate an ambiguous, inconsistent, or changed obligation for human decision. A new baseline if approved, plus review of affected artifacts and evidence.

PROVE is a workflow label, not a claim of formal proof. It means produce the configured evidence and identify what that evidence establishes.

Diagram
The implementation loop may repeat freely inside its authorised scope. Returning to the contract requires human review.

These are decision stages, not a requirement for twelve separate people, prompts, or tools. A small team can combine execution roles while still making approvals, baselines, and exceptions explicit.

1–2. Scope and Intent

Start by choosing what the agent is allowed to solve. “Build a website” is not a useful boundary. Neither is “make the platform secure.” Both invite the model to invent a product, architecture, and verification strategy before the owners have agreed on the outcome.

Worked example: static Markdown rendering

The concept page already supplies a concrete requirement: Markdown content is parsed at build time, rendered as static pages, and published at canonical URLs. Mermaid diagrams become inline SVG. The site must remain usable without browser JavaScript.

For this example, bound the work to that rendering slice:

Scope element Example decision
Actor The site author publishing Markdown content.
Input Markdown files with YAML frontmatter and supported diagram/link syntax.
Required outcome Static HTML containing the expected metadata-derived content, inline diagrams, and canonical internal links.
Operating constraint Readers must not need browser JavaScript to access the published content and diagrams.
Outside this slice A dynamic CMS, user accounts, and unrelated site features. These are illustrative scoping exclusions.
Open questions Exact canonical-path rules, accepted metadata, and behaviour for unsupported or invalid inputs.
Decision owner The human responsible for the site's content and delivery contract.

The scoped intention can now be expressed without selecting an implementation architecture:

When the build processes an authored Markdown page, publish a static page at its canonical URL, with its frontmatter interpreted, its diagrams rendered as inline SVG, and its internal links resolved. The published result must remain readable without browser JavaScript.

Keep unresolved questions unresolved. An AI-proposed default is a candidate decision, not an inherited business fact. For example, an error policy for malformed frontmatter requires a decision; the agent must not silently choose between failing the build, omitting the page, or publishing fallback content.

3–4. Elicit and Materialize

Ask the model to elaborate the bounded intention into requirements, not to jump directly to production code. Explore the relevant business, system, capability, and component obligations, and the functional and non-functional concerns. Do not manufacture a requirement in every category just to fill a matrix: an excluded or not-applicable concern should have an explicit reason.

For this slice, useful questions include whether the published page contains the expected content, whether diagrams require runtime JavaScript, and whether links resolve correctly. Performance, accessibility, security, or reproducibility obligations require their own agreed conditions and fit criteria; the word “industrial” does not supply those conditions automatically.

A candidate-generation instruction

This is an example operating instruction, not a library API or a security boundary:

Work only within the supplied scope and intent.

Propose requirements in the project's existing typed vocabulary.
For each candidate, preserve its statement, rationale, source, risk,
fit criteria, assumptions, and unresolved decisions where supported.

Distinguish requirements from proposed solutions.
Cover relevant abstraction levels and verification concerns.
Explain exclusions rather than inventing obligations to fill a template.

Produce candidate TypeScript or C# declarations for review.
Do not mark candidates Approved, Implemented, or Verified on your own.
Do not generate the production implementation yet.

Also produce a readable projection so the owner can review the same
candidate model without relying on source-code fluency.

The important output of MATERIALIZE is a type system for the problem–solution contract, not another document that an agent will have to reinterpret. The readable review view must reference the same candidate revision.

Materializing requirements as code must not be confused with implementing the requested capability. Writing a requirement class does not justify an Implemented lifecycle state.

TypeScript representation

The reference model uses a Requirement class with statement, rationale, provenance, risk, and fit criteria. The companion page supplies the full ContentMustLoadFromMarkdown declaration. Candidate authoring uses that vocabulary before human approval; the baseline later records the approved revision.

The feature below is the derived capability reviewed in stage 7. It is shown here to make the target representation concrete. It is the existing three-criterion example, not a new package API:

import {
  Feature,
  Priority,
  Satisfies,
  type ACResult,
} from '@frenchexdev/requirements';
import { ContentMustLoadFromMarkdown } from '../requirements/content-loading';

@Satisfies(ContentMustLoadFromMarkdown)
export abstract class MarkdownPageRendering extends Feature {
  readonly id = 'FEAT-MD-RENDER';
  readonly title = 'Markdown Page Rendering';
  readonly priority = Priority.Critical;

  abstract frontmatterIsParsed(): ACResult;
  abstract mermaidPlaceholdersAreReplaced(): ACResult;
  abstract internalLinksResolveToCanonicalPaths(): ACResult;
}

@Satisfies declares a relationship. It does not prove that the implementation satisfies the requirement. The abstract methods declare AC identities; tests provide the observations and assertions.

This excerpt follows the V2's portable form without decorators on abstract methods. Expected verification levels still need a compatible, machine-readable representation in the consuming project. Do not assume that an annotation shown in a design example is supported by every TypeScript compiler configuration.

C# representation

The documented C# foundation uses Epic at the requirement tier and a constrained Feature<TParent> hierarchy:

using FrenchExDev.Net.Requirements;
using FrenchExDev.Net.Requirements.Attributes;

namespace Site.Requirements;

[MetaConcept]
public abstract class ContentLoading : Epic
{
    public override string Title =>
        "Page content authored in Markdown, rendered at build time";
    public override RequirementPriority Priority => RequirementPriority.Critical;
    public override string Owner => "stephane.erard@gmail.com";
}

[MetaConcept]
[ForRequirement(typeof(ContentLoading))]
public abstract class MarkdownRendering : Feature<ContentLoading>
{
    public override string Title => "Markdown Page Rendering";
    public override RequirementPriority Priority => RequirementPriority.Critical;
    public override string Owner => "stephane.erard@gmail.com";

    public abstract AcceptanceCriterionResult FrontmatterIsParsed();
    public abstract AcceptanceCriterionResult MermaidPlaceholdersAreReplaced();
    public abstract AcceptanceCriterionResult InternalLinksResolveToCanonicalPaths();
}

These are API illustrations that require the actual packages and consuming-project setup. The C# foundation does not establish complete parity with TypeScript's richer provenance, lifecycle, or tooling. Unsupported metadata and approval records need an explicit integration; the agent must not invent attributes and describe them as existing exports.

5–6. Review and Freeze

The owner reviews candidate meaning, not just syntax. A structurally valid requirement can still be wrong, incomplete, infeasible, or outside the intended scope.

Green / red / refine

Decision Meaning Example in this slice
Green Approve this candidate and revision. Parse the agreed frontmatter fields into the metadata used by rendering.
Red Reject the candidate. Preserve the reason where useful. Require a browser-side Mermaid runtime: it conflicts with the approved no-JavaScript reading constraint.
Refine Neither approved nor discarded; return with questions or edits. “Resolve every link correctly” needs explicit canonical-path rules and supported input cases.

The decisions above illustrate the review mechanism; they are not historical approvals. Approval of the overall intention does not automatically approve every requirement an AI derives from it.

Diagram
Approval is attached to a reviewed revision. A status field and a passing compiler are not substitutes for that decision.

Freeze means controlled change, not waterfall. Freeze a useful slice, implement it, and repeat. A project can continue discovering future requirements without changing the contract of work already being evaluated.

What the baseline must identify

The integration should identify the approved scope, typed requirement revision, source/provenance, decision owner, and approval record. Stage 7 then adds separately reviewed Feature/AC declarations and verification policy revisions to the delivery reference.

This separation avoids a trap: freezing the requirements and then letting an agent redefine them through “derived” acceptance criteria. Derivation may refine an obligation without changing its meaning. Any new obligation, changed threshold, or changed exclusion returns to REVIEW/CHANGE. Before synthesis, both the requirement baseline and the verification plan must be fixed for that attempt.

A useful delivery reference is therefore:

approved requirement baseline
+ reviewed Feature/AC revision
+ approved verification-policy revision
+ pinned toolchain and relevant configuration

The TypeScript library documents content-hash versioning and drift detection. The integration must still check which fields participate in the hash. An excluded field cannot be assumed protected merely because the overall object has a hash. A signature or status = 'Approved' also needs an actual approval identity and protected storage to carry governance meaning.

7–8. Derive and Verify First

With the requirement slice approved, derive the capability, ACs, and verification obligations. AI can propose this decomposition, but the resulting plan needs review before it becomes the target for implementation.

The verification question is not “how many tests can the model write?” It is which observations would support or falsify each approved obligation?

Separate verification level from concern

A level describes where a check runs: unit, integration, or end-to-end. A concern describes what it addresses: functional correctness, accessibility, internationalisation, visual behaviour, performance, security, or another approved concern.

Do not flatten these into a single list of interchangeable labels. A visual check can run end-to-end. A performance obligation can need several levels. Ten unit tests do not replace one required end-to-end scenario.

The concept page's three ACs provide this starting point:

AC Source example's expected verification What the result must not be mistaken for
frontmatterIsParsed Unit and end-to-end. A correct parser unit test alone does not establish that the published page uses the metadata.
mermaidPlaceholdersAreReplaced Unit. Finding <svg in one returned string does not, by itself, establish every diagram's correctness or browser behaviour.
internalLinksResolveToCanonicalPaths End-to-end and visual. A string-rewrite unit test is not the required browser-level result.

The broader requirement also includes a no-JavaScript fit criterion. It must not disappear merely because none of the three method names explicitly says worksWithoutJavaScript. The reviewed plan must show how that requirement-level obligation is covered—through appropriate end-to-end scenarios or an explicitly reviewed AC refinement. Mapping a check to a convenient method name is not enough.

For this worked example, the proposed plan uses a browser with JavaScript disabled for the relevant end-to-end checks. This is an explicit test-plan design based on the source requirement, not a claim that those tests already exist.

A typed plan rather than a second Markdown contract

The table above explains the plan to a reader. It cannot be the only place where required checks are declared.

The following is a proposed consumer-side TypeScript model, not an export of @frenchexdev/requirements. It illustrates how this zero-argument AC example can require a non-empty verification plan for every AC-shaped member. The consuming project must connect the plan to actual test discovery and result validation.

import type { ACResult } from '@frenchexdev/requirements';
import type { MarkdownPageRendering } from './features/markdown-rendering';

// For this example, ACs are zero-argument methods returning ACResult.
type AcName<F> = Extract<{
  [K in keyof F]-?: F[K] extends () => ACResult ? K : never;
}[keyof F], string>;

type Level = 'unit' | 'integration' | 'end-to-end';
type Concern = 'functional' | 'visual';
type Environment = 'unit-runner' | 'browser-js-disabled';

type Obligation = {
  readonly level: Level;
  readonly concern: Concern;
  readonly environment: Environment;
};

type VerificationPlan<F> = {
  readonly [K in AcName<F>]: readonly [Obligation, ...Obligation[]];
};

export const markdownVerificationPlan = {
  frontmatterIsParsed: [
    { level: 'unit', concern: 'functional', environment: 'unit-runner' },
    {
      level: 'end-to-end',
      concern: 'functional',
      environment: 'browser-js-disabled',
    },
  ],
  mermaidPlaceholdersAreReplaced: [
    { level: 'unit', concern: 'functional', environment: 'unit-runner' },
  ],
  internalLinksResolveToCanonicalPaths: [
    {
      level: 'end-to-end',
      concern: 'functional',
      environment: 'browser-js-disabled',
    },
    {
      level: 'end-to-end',
      concern: 'visual',
      environment: 'browser-js-disabled',
    },
  ],
} as const satisfies VerificationPlan<MarkdownPageRendering>;

This catches particular structural mistakes: missing AC entries, unknown keys in this object literal, invalid labels, and empty obligation lists. It does not establish that the combinations are adequate, that the no-JavaScript obligation is fully covered, or that any test ran. This return-signature filter is also an example convention, not a universal definition of an AC. The model deliberately covers only the functional and visual obligations shown; other approved concerns need their own representation.

A production plan additionally needs scenario identity, expected outcome or approved threshold, risk, evidence requirements, and a mapping to the runner. That integration must reject missing and incompatible results. Without it, the plan is typed documentation, not an operational gate.

Generate tests against the reviewed obligations

The TypeScript binding from the concept page looks like this:

import { expect } from 'vitest';
import { FeatureTest, Verifies } from '@frenchexdev/requirements';
import { MarkdownPageRendering } from '../../requirements/features/markdown-rendering';
import { renderMarkdownPage } from '../../src/lib/markdown-renderer';

@FeatureTest(MarkdownPageRendering)
class MarkdownPageRenderingTests {
  @Verifies<MarkdownPageRendering>('frontmatterIsParsed')
  'extracts title and section from YAML frontmatter'() {
    const page = renderMarkdownPage(
      '---\ntitle: About\nsection: about\n---\n# Hello',
    );

    expect(page.meta.title).toBe('About');
    expect(page.meta.section).toBe('about');
    expect(page.body).toContain('<h1>Hello</h1>');
  }
}

The class-based form depends on the project's test-registration integration. A decorated class sitting undiscovered in a source file is not a test run. The generic name constraint helps reject invalid member names; the scanner must still validate that the selected member is an AC and that the binding belongs to the intended feature.

The corresponding C# binding uses the documented attributes and xUnit integration:

using Xunit;
using FrenchExDev.Net.Requirements.Attributes;
using Site.Requirements;
using Site.Rendering;

namespace Site.Requirements.Tests;

[TestsFor(typeof(MarkdownRendering))]
public class MarkdownRenderingTests
{
    [Fact]
    [Verifies(typeof(MarkdownRendering),
              nameof(MarkdownRendering.FrontmatterIsParsed))]
    public void Extracts_title_and_section_from_yaml_frontmatter()
    {
        var page = MarkdownRenderer.Render(
            "---\ntitle: About\nsection: about\n---\n# Hello");

        Assert.Equal("About", page.Meta.Title);
        Assert.Equal("about", page.Meta.Section);
        Assert.Contains("<h1>Hello</h1>", page.Body);
    }
}

nameof resolves a symbol and produces a string constant. It protects against a missing referenced member, but it does not by itself validate the pairing of that member with the feature passed to the attribute. Semantic checks must establish that relationship.

Both snippets illustrate one unit check. Neither completes the verification plan. End-to-end and visual obligations remain outstanding until the appropriate checks are implemented, discovered, executed, and evaluated.

Establish that a test can detect the missing behaviour

Where practical, observe the new check fail against the previous or deliberately faulty implementation before accepting the repair. Record the reason for the failure. Missing credentials, an unavailable browser, or a broken runner does not demonstrate a useful behavioural failure.

For properties, contracts, inspections, or infrastructure checks, “verify first” means defining the expected observation and verification procedure before deriving the expected answer from the implementation. It is not a demand to force every concern into a unit test.

Diagram
The model receives real execution feedback. It does not supply the authoritative result by narrating that the tests passed.

9–10. Synthesize and Prove

The implementation agent now receives a bounded context package: the approved requirement baseline, reviewed Features/ACs and verification policy, relevant interfaces, architecture constraints, permitted paths, and the project's pinned execution commands.

Do not substitute a prose summary for the actual declarations. Different models or runs should work against the same model revision. This reduces untracked reinterpretation; it does not make their reasoning deterministic.

Generate an architecture that earns its complexity

The workflow explicitly includes POSA, SOLID, DRY, modularity, and appropriate patterns as design inputs. They are design disciplines, not instructions to produce the maximum number of abstractions.

In this example, separating frontmatter parsing, diagram rendering, canonical-link resolution, and page assembly may make the obligations easier to test and the implementation easier to change. That is a design proposal to evaluate, not a new requirement hidden inside the prompt. Reuse existing boundaries where they already serve the purpose.

AI can propose alternatives and explain dependencies or trade-offs. The reviewer should be able to connect important decisions to approved constraints. A new dependency, runtime assumption, or service that changes the delivery contract needs a decision, not an incidental import.

Give the implementation agent a bounded mandate

INPUT
Use the approved requirement baseline and reviewed verification plan
at the exact revisions supplied by the workflow.
Read the typed declarations, relevant interfaces, and approved decisions.

WORK
Implement only the selected slice.
Propose tests that challenge the approved outcomes.
Use POSA, SOLID, DRY, modularity, and patterns pragmatically.
Prefer explicit, maintainable boundaries over speculative abstraction.

BOUNDARIES
Do not change approved requirements, AC semantics, thresholds,
required verification levels, exclusions, or gate configuration.
Do not claim an unexecuted check passed.
Do not treat generated documentation as a newer authority.
Request a human decision when the contract is ambiguous or infeasible.

OUTPUT
Return the proposed changes and their Requirement/Feature/AC links.
Identify the commands actually run, results, missing evidence,
remaining assumptions, and any requested contract change.
A local success does not authorise merge, approval, or release.

These instructions express the mandate. Permissions and review controls must enforce the relevant boundaries.

Use the existing ecosystem mechanisms

Responsibility TypeScript integration path C# integration path
Represent the model Requirement/Feature classes, AC declarations, decorators. Constrained hierarchy, AC declarations, attributes.
Resolve relationships Type checking plus the documented AST/binding scanner. Type checking plus Roslyn analysis where implemented.
Expose the model Bindings manifest, trace graph, command cores. Generated RequirementRegistry.g.cs and its consumers.
Execute verification Registered tests and the project's test/adaptor integrations. Test-framework discovery and project-specific verification integrations.
Enforce acceptance Compliance results joined to the reviewed plan and applicable run results. Implemented diagnostics and registry consumers joined to the reviewed plan and run results.
Collect evidence and approvals Consuming-project CI, storage, permissions, and reviews. The same integration responsibilities; the generator does not replace them.

The documented TypeScript CLI surface includes:

npx requirements trace gaps
npx requirements scaffold e2e FEAT-MD-RENDER
npx requirements compliance --strict

Use the consuming project's pinned installation and scripts, not an unspecified package fetched during a production run. Scaffolding creates a starting point; it does not verify the requirement. The exact data used by the compliance command must be understood before its green output becomes a release condition.

The C# documentation describes the structural foundation and registry generator; its snapshot reports REQ100 as implemented and REQ101–REQ302 as scaffolded or in progress. These are documentary status claims, not a fresh package audit. A reserved diagnostic ID must not be treated as a functioning gate. Qualify each required rule on the selected package with positive and deliberately invalid fixtures, and configure it to block the intended workflow.

Separate the gates

The delivery pipeline should keep these outcomes distinguishable:

Gate Question
Type and build Are declarations, references, generic constraints, and the implementation valid under the selected toolchain?
Semantic bindings Do the recorded Requirement → Feature → AC → Test relationships resolve under the implemented rules?
Verification completeness Are all required scenarios, levels, concerns, and environments represented?
Execution Did those checks actually run against the intended artifacts, and what happened?
Coverage and mutation Which paths were exercised, and which selected artificial faults were detected?
Evidence applicability Do the results apply to the approved model, policy, code, configuration, and environment?
Acceptance authority Has the authorised owner accepted the slice and any explicit exceptions?
Diagram
Compiler success is one input to acceptance. Runtime results, evidence applicability, and decision authority remain separate.

This is logical orchestration, not a prescribed CI vendor or an assertion that all checks run sequentially. Independent checks can run in parallel while preserving their inputs and outcomes.

Put Stryker in the feedback loop

The intended loop includes Stryker mutation testing: use the project's appropriate, pinned integration to challenge test sensitivity after establishing a working test run. The workflow does not prescribe unverified installation commands or imply that Stryker is built into either Requirements-as-Code library.

A surviving mutant is a question to investigate. It may reveal a missing assertion, missing scenario, unreachable code, an equivalent change, or a configuration problem. AI can help analyse it and propose a better test. The improvement must still test approved behaviour rather than a detail invented solely to increase a score.

For the Markdown example, useful fault hypotheses include:

Fault hypothesis Verification weakness it may expose
A parser returns a default section instead of the supplied section. The test checks the title but never the section.
A renderer leaves an internal .md link unchanged. A test checks that a link exists without checking the canonical target.
Diagram replacement emits an empty SVG container. An assertion only searches for the substring <svg.

These are illustrative fault hypotheses, not executed mutation results or a promise that a built-in mutator produces all three. Some require deliberately faulty fixtures or additional verification rather than a standard mutation operator.

Do not remove a surviving mutant from the denominator merely to make the report green. Review exclusions and equivalent-mutant decisions under the agreed policy. A mutation score is evidence about the selected fault model, not proof of requirement completeness.

Bind evidence to what was actually evaluated

The consuming pipeline should record the requirement baseline, Feature/AC and policy revisions, implementation/test revision, artifact identity, environment/configuration, runner versions, discovered and executed checks, outcomes, and report locations. These are evidence-integration requirements, not an existing universal payload schema shared by both libraries.

An illustrative outcome for this slice might read:

Illustration only — not execution output

Type check and semantic binding checks: pass
Frontmatter unit check: pass
Required end-to-end checks: not executed
Required visual verification: missing
Mutation analysis: not executed

Acceptance candidate: NO
Reason: the approved verification obligations are incomplete.

That result remains incomplete even when every existing test passes. Not run, skipped, stale, blocked, and failed must not be normalised into “verified.”

11–12. Iterate and Change

A failed gate has several possible meanings. The workflow must classify the failure before deciding what the agent is authorised to modify.

Repair within the contract

If the implementation violates an approved AC, repair the implementation. If a test is incorrect or inadequate, propose a correction and review it against the approved obligation. Tests are not infallible; keeping a wrong test forever is not governance.

The boundary is whether the change preserves the contract. Adding an assertion that the supplied section is retained can strengthen verification of the existing requirement. Removing a required end-to-end check because the current implementation cannot pass it changes the verification obligation and requires approval.

The agent may iterate on authorised work, but it must stop and report a blocker when an essential decision or environment is missing. An unavailable browser or absent credentials cannot be repaired by changing the result to “pass.”

Request a contract change

A change proposal should identify the affected requirement/AC, the ambiguity or conflict, the proposed revision, alternatives, implications, and the known dependent artifacts. The human may approve, reject, or refine it through the original decision loop.

Suppose the link policy changes after delivery work begins. Existing member names may remain valid and the project may still compile. That does not make yesterday's expected URL correct under the new rule. The affected requirements, fit criteria, verification expectations, implementation, and evidence must be reviewed together.

Diagram
Failure is diagnostic information. It does not grant the agent permission to redefine success.

Preserve history; reassess applicability

Old evidence remains evidence of the old run. Do not rewrite it to make it look current, and do not automatically discard it as meaningless. Determine which recorded obligations, code, configuration, and environments changed.

A conservative policy marks affected evidence as needing reassessment until its applicability is established. Unchanged checks may remain useful where the policy permits reuse and the dependency record supports it. An unrecorded dependency is a modelling gap, not something the trace graph can magically discover.

This is especially important for semantic changes that preserve names and types. A rename failure is useful, but unchanged symbols do not establish unchanged meaning. Versioning, content review, and evidence applicability checks complement the compiler.

The approved lifecycle and the work-attempt status also differ. “The agent finished its task,” “the implementation compiles,” and “the requirement is verified” are not interchangeable transitions.

Protect the Contract, the Gate, and the Evidence

The preceding prompts describe expected behaviour. An industrial integration also needs controls that survive a mistaken or overreaching agent action.

Separate proposal rights, approval rights, execution authority, and release authority. One person may hold several roles in a small project, but an automated producer should not silently inherit all of them.

Surface AI contribution Required control
Requirements and ACs Draft candidates and propose revisions. Human approval of the selected revision; protected baseline history.
Verification policy and exclusions Explain gaps and propose changes. Independent review of changes that alter how success is judged.
Tests and implementation Create and repair within scope. Review that distinguishes a legitimate test correction from weakened acceptance.
CI and tools Execute permitted local commands and inspect results. Protected acceptance workflow and pinned execution configuration.
Evidence Read results and explain failures. Authoritative results collected from the runner, not an agent-authored success summary.
Acceptance and deployment Prepare a candidate and its evidence. Approval by the designated authority; no self-approval by the producing agent.

Before using AI, establish which provider, model deployment, data classes, repository access, tools, credentials, logging, retention, and external processing are permitted by the project. Keep confidential source and business data within the approved environment. An agent's need for context is not permission to send it elsewhere.

Protect the verification system itself. Run negative fixtures to show that missing bindings, invalid references, skipped required checks, and altered policy are rejected where the gate claims to reject them. A process cannot rely on a control merely because its configuration file exists.

Different AI agents can help with elicitation, implementation, and test review, but a second model is not automatically an independent oracle. Shared assumptions can still produce a coherent but wrong requirement–test–implementation combination. Human review, approved fit criteria, and meaningful execution remain necessary.

The same model works without AI. AI is an interchangeable producer within the workflow; the contract and acceptance authority should not depend on a particular model staying in the loop.

Definition of Done

A delivered slice should make the following questions answerable from its artifacts, not from the implementer's recollection:

Question Required answer
What was approved? The requirement baseline, scope, provenance, and approval decision.
What capability addresses it? The reviewed Feature/AC model and relevant architecture decisions.
How was it evaluated? The verification-policy revision, required scenarios, levels, concerns, and environments.
What actually ran? Discovered and executed checks, outcomes, skips, exclusions, and blocking conditions.
What do the results apply to? The model, implementation, artifact, configuration, and environment revisions.
What remains uncertain? Gaps, limitations, residual risks, and any explicitly approved exceptions.
Who accepted the result? The designated owner and the recorded acceptance decision.

A human decision to accept an explicit exception must remain visible as an exception. It must not relabel a failed or unexecuted check as successful evidence.

For the Markdown slice, this means more than a valid MarkdownPageRendering declaration. It means the approved parsing, diagram, and link obligations have the required observations against the produced pages, including the applicable no-JavaScript checks. A green unit-test suite alone does not complete that obligation.

The same sequence can apply to a platform-automation capability: derive approved provisioning and operational obligations, connect them to the relevant delivery artifacts, and execute appropriate checks. Terraform, Ansible, or other automation tools remain execution tools. Linking them into this workflow is an integration pattern, not a released adapter implied by this article.

Keep the guarantees precise

well-typed                 ≠ correctly specified
bound to an AC             ≠ discovered by the test runner
discovered                 ≠ executed
executed                   ≠ passed
passed                     ≠ exhaustive
high source coverage       ≠ strong assertions
high mutation score        ≠ complete requirements
previously passing evidence ≠ evidence for a changed contract

The value is not the promise that every error becomes a compiler error. It is that each obligation has a representation, each check has a defined role, and each acceptance claim points to applicable evidence.

The Workflow in One Sentence

Start with scoped intent or explore candidate requirements from existing code and tests. Materialize the candidates as types, obtain human green/red/refine decisions, freeze the approved slice, derive and review verification obligations, develop tests and a pragmatic implementation, challenge both with mechanical feedback, and change the contract only through a new authorised decision.

The model may change. The implementation may change. The AI may change. What must not change silently is the definition of success.

Requirements-as-Code supplies the conceptual model, the Markdown-rendering example, the two implementation descriptions, and their stated boundaries. Spec-Driven vs Typed Specifications provides the earlier framing under the prototype name. AI-Driven Self-Implementation is related background on feature-driven agent work and feedback.

The descriptions here follow the Requirements-as-Code V2 documentary baseline. TypeScript is the documented live reference implementation; C# supplies the documented hierarchy, attributes, registry, and analyzer foundation. Complete parity, every reserved analyzer, cross-language interchange, and turnkey evidence governance are not assumed.

The typed verification-plan example is a proposed consumer integration. Package-facing excerpts require the actual dependencies, registration, and rendering implementation. No sample result in this article is presented as execution evidence, and no historical compliance percentage is used as a current assurance claim.

⬇ Download