contrib: added protocols for requirements management

Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
This commit is contained in:
Nikos Mavrogiannopoulos
2026-06-06 12:16:11 +02:00
parent 14b5295e8f
commit b23c939d29
5 changed files with 821 additions and 0 deletions
+41
View File
@@ -54,6 +54,47 @@ State the specific principle violated and the minimal change that would satisfy
---
## Protocol: Requirements Elicitation
Load and follow `contrib/ai/protocols/requirements-elicitation.md` when converting
a natural language feature or design description into structured requirements. The
ocserv-specific extensions cover: process assignment (`[PROC: main/sec-mod/worker]`),
mandatory negative requirements for `SEC`/`AUTH`/`IPC` categories, canonical category
tags (`AUTH`, `IPC`, `CFG`, `SEC`, `NET`, `COMPAT`, `ACCT`, `LOG`), implicit constraint
flags for Linux-only interfaces and seccomp, ambiguity patterns specific to ocserv
terminology (session, reload, secure), and test infrastructure mapping for acceptance
criteria.
---
## Protocol: Requirements from Implementation
Load and follow `contrib/ai/protocols/requirements-from-implementation.md` when
reverse-engineering what an existing module guarantees. The ocserv-specific extensions
cover: the `auth_mod_st` vtable as the primary auth API surface, IPC message fields
(`src/ipc.proto`, `src/ctl.proto`) as entry points, talloc ownership as the primary
precondition to establish, the documentation test (`doc/ocserv.8.md` / `doc/sample.config`
as the essential-behavior oracle), process safety in place of thread safety, and
additional gap checks for vtable NULL-safety, IPC field coverage, config ↔ doc
alignment, reload coverage, and seccomp coverage.
---
## Protocol: Requirements Reconciliation
Load and follow `contrib/ai/protocols/requirements-reconciliation.md` when aligning
requirements across multiple sources — the OpenConnect protocol (`OC-PROTO`), observed
Cisco AnyConnect client behavior (`AC-CLIENT`), IETF RFCs (`RFC-TLS`, `RFC-DTLS`), and
the ocserv implementation (`OCSERV`). The ocserv-specific extensions define the standard
source inventory, functional area coverage matrix, alignment anchors (CSTP headers,
HTTP exchange phases, TLS parameters), AnyConnect-specific classification rules
(`[COMPAT-RISK]`, `[COMPAT-CRITICAL]`), security-downgrade handling (`[SEC-RISK]`),
and unified category tags (`CONN`, `AUTH`, `SESSION`, `DATA`, `CTRL`, `CFG`, `COMPAT`,
`SEC`, `EXT`). Always read `doc/README-cisco-svc.md` before starting the source
inventory.
---
## Protocol: Anti-Hallucination
This is a C codebase with specific library APIs, IPC field names, and kernel interfaces.
@@ -0,0 +1,212 @@
<!-- SPDX-License-Identifier: MIT -->
<!-- Copyright (c) PromptKit Contributors -->
---
name: requirements-elicitation
type: reasoning
description: >
Protocol for extracting, structuring, and validating requirements
from natural language descriptions. Produces precise, testable,
unambiguous requirements with stable identifiers.
applicable_to:
- author-requirements-doc
- interactive-design
- hardware-design-workflow
---
# Protocol: Requirements Elicitation
Apply this protocol when converting a natural language description of a feature,
system, or project into structured requirements. The goal is to produce
requirements that are **precise, testable, unambiguous, and traceable**.
## Phase 1: Scope Extraction
From the provided description:
1. Identify the **core objective**: what problem does this solve? For whom?
2. Identify **explicit constraints**: performance targets, compatibility
requirements, regulatory requirements, deadlines.
3. Identify **implicit constraints**: assumptions about the environment,
platform, or existing system that are not stated but required.
Flag each with `[IMPLICIT]`.
4. Define **what is in scope** and **what is out of scope**. When the
boundary is unclear, enumerate the ambiguity and ask for clarification.
## Phase 2: Requirement Decomposition
For each capability described:
1. Break it into **atomic requirements** — each requirement describes
exactly one testable behavior or constraint.
2. Use **RFC 2119 keywords** precisely:
- MUST / MUST NOT — absolute requirement or prohibition
- SHALL / SHALL NOT — equivalent to MUST (used in some standards)
- SHOULD / SHOULD NOT — recommended but not absolute
- MAY — truly optional
3. Assign a **stable identifier**: `REQ-<CATEGORY>-<NNN>`
- Category is a short domain tag (e.g., AUTH, PERF, DATA, UI)
- Number is sequential within the category
4. Write each requirement in the form:
```
REQ-<CAT>-<NNN>: The system MUST/SHALL/SHOULD/MAY <behavior>
when <condition> so that <rationale>.
```
## Phase 3: Ambiguity Detection
Review each requirement for language that introduces non-deterministic
interpretation. Apply the ambiguity pattern categories below
systematically; these categories are aligned with the
`prompt-determinism-analysis` protocol:
1. **Vague adjectives**: "fast," "responsive," "secure," "scalable,"
"user-friendly" — replace with measurable criteria.
2. **Unquantified quantities**: "handle many users," "large files" —
replace with specific numbers or ranges.
3. **Implicit behavior**: "the system handles errors" — what errors?
What does "handle" mean? Retry? Log? Alert? Fail open? Fail closed?
4. **Undefined terms**: if a term could mean different things to different
readers, add it to a glossary with a precise definition.
5. **Missing negative requirements**: for every "the system MUST do X,"
consider "the system MUST NOT do Y" (e.g., "MUST NOT expose PII in logs").
6. **Open-ended enumerations**: "support formats like PDF, Word, etc." —
enumerate the complete list or define the selection criterion
(e.g., "all formats supported by the pandoc library").
7. **Hedge words in requirements**: "the system could support" or
"consider adding" — these must be resolved to MUST, SHOULD, or MAY.
If the user cannot decide, classify as MAY and flag for review.
8. **Missing conditional branches**: "if the user is authenticated,
show the dashboard" — what happens if NOT authenticated? Add
explicit else-branches for every conditional requirement.
9. **Unanchored comparatives**: "faster than the current system" —
anchor to measurable baselines (e.g., "response time under 200ms
at the 95th percentile, compared to the current 500ms").
## Phase 4: Dependency and Conflict Analysis
1. Identify **dependencies** between requirements: which requirements
must be satisfied before others can be implemented or tested?
2. Check for **conflicts**: requirements that contradict each other
or create impossible constraints.
3. Check for **completeness**: are there scenarios or edge cases
that no requirement covers? If so, draft candidate requirements
and flag them as `[CANDIDATE]` for review.
## Phase 5: Acceptance Criteria
For each requirement:
1. Define at least one **acceptance criterion** — a concrete test that
determines whether the requirement is met.
2. Acceptance criteria should be:
- **Specific**: describes exact inputs, actions, and expected outputs.
- **Measurable**: pass/fail is objective, not subjective.
- **Independent**: testable without requiring other requirements to be met
(where possible).
<!-- BEGIN ocserv extensions -->
## ocserv-Specific Extensions
The sections below extend the generic protocol with ocserv's privilege model,
configuration constraints, and project conventions. Apply these alongside the
base phases above.
### Phase 1 — Scope Extraction (ocserv)
In addition to the generic checklist, for every new feature or change:
- **Assign to a process.** Every requirement belongs to exactly one process:
- `[PROC: main]` — TCP/UDP listener, TUN device, IP allocation, process lifecycle
- `[PROC: sec-mod]` — authentication, private keys, session state, PAM, accounting
- `[PROC: worker]` — per-client TLS/DTLS, VPN traffic, protocol handling
- `[PROC: IPC]` — a behavior that requires a new or modified message between processes
If a requirement touches more than one process, decompose it into per-process
sub-requirements connected by an IPC requirement.
- **Flag Linux-only implicit constraints.** If the feature relies on Linux-specific
interfaces (epoll, TUN, procfs, namespaces, cgroups), add:
`[IMPLICIT: Linux-only; BSD builds will require a no-op stub]`.
- **Flag worker seccomp constraints.** Any requirement that causes the worker to
invoke a system call not currently in the seccomp whitelist must be flagged:
`[IMPLICIT: requires seccomp filter update; needs maintainer review]`.
- **Configuration format.** If the feature is user-configurable, the configuration
MUST be expressible as INI `key = value` pairs or the existing bracketed
sub-section syntax (`auth = module[key=value]`). Flag any requirement that
assumes structured formats (JSON, YAML) as `[VIOLATION: configuration format]`.
### Phase 2 — Requirement Decomposition (ocserv)
Use these category tags for `REQ-<CAT>-<NNN>` identifiers:
| Tag | Domain |
|-----|--------|
| `AUTH` | Authentication logic (sec-mod, auth backends) |
| `ACCT` | Accounting (session start/stop, RADIUS, PAM acct) |
| `IPC` | Inter-process communication (ipc.proto, ctl.proto) |
| `CFG` | Configuration parsing and defaults |
| `SEC` | Security properties (trust boundaries, seccomp, privilege) |
| `NET` | TLS/DTLS, TCP/UDP, IP allocation, routing |
| `COMPAT` | AnyConnect / OpenConnect client compatibility |
| `LOG` | Logging, error messages, diagnostics |
**Negative requirements are mandatory for `SEC`, `AUTH`, and `IPC` categories.**
For every `REQ-SEC-*` or `REQ-AUTH-*` MUST requirement, write at least one
corresponding MUST NOT requirement. Examples:
- `REQ-SEC-001: The worker MUST NOT have direct access to private keys or
session credentials. All credential operations MUST go through sec-mod via IPC.`
- `REQ-IPC-001: A worker MUST NOT accept IPC messages that contain a SID it
did not receive via SEC_AUTH_REP.`
### Phase 3 — Ambiguity Detection (ocserv)
Additional ambiguity patterns to check in the ocserv context:
- **"Secure"**: Always replace with a concrete property — e.g., "authenticated
via TLS client certificate," "protected from replay by SID validation,"
"isolated by seccomp from filesystem access."
- **"Session"**: Disambiguate — is this a TLS session, a VPN session (identified
by SID), a cookie-resumable session, or a PAM session?
- **"Reload"**: Disambiguate — config reload via `SIGHUP` (may not apply to all
options), or full restart? Check `doc/sample.config` for the option's reload
behavior annotation (`[reload]` vs. `[not-reloadable]`).
- **"All clients"**: Specify — does this apply during active sessions, or only
to new connections? Does it apply to DTLS sessions as well as TLS?
### Phase 4 — Dependency and Conflict Analysis (ocserv)
Check for these ocserv-specific conflicts before finalizing requirements:
- **Process boundary conflicts**: A requirement `[PROC: worker]` that accesses
state that belongs to `[PROC: sec-mod]` without an `[PROC: IPC]` requirement
is a privilege model violation.
- **Config reload conflicts**: A requirement that changes behavior at runtime
via a reload must be consistent with which options are marked reloadable in
`doc/sample.config`. Non-reloadable options that appear to need live update
are a conflict requiring explicit resolution.
- **AnyConnect compatibility conflicts**: If a requirement changes protocol
behavior, check `doc/README-cisco-svc.md` for AnyConnect client expectations.
A conflict with AnyConnect behavior must be flagged as `[COMPAT-RISK]`.
### Phase 5 — Acceptance Criteria (ocserv)
Map each acceptance criterion to the ocserv test infrastructure:
- **Positive test**: shell test in `tests/` that starts the full server stack
and exercises the feature. Most such tests require root and will run in CI only.
- **Negative test**: shell test that verifies the server correctly rejects bad
input or enforces the MUST NOT requirement. Write this first for `SEC`, `AUTH`,
and `IPC` requirements.
- **Unit test**: a `tests/*.c` unit test for logic that does not require a full
server (config parsing, data structure operations). These run locally without root.
- **Registration**: every new test must be registered in `tests/meson.build`.
Note in the acceptance criterion whether it is locally runnable or requires CI
(root / full server stack).
<!-- END ocserv extensions -->
@@ -0,0 +1,261 @@
<!-- SPDX-License-Identifier: MIT -->
<!-- Copyright (c) PromptKit Contributors -->
---
name: requirements-from-implementation
type: reasoning
description: >
Systematic reasoning protocol for deriving structured requirements
from existing source code. Transforms code understanding into
testable, atomic requirements with acceptance criteria.
applicable_to:
- reverse-engineer-requirements
- review-code
---
# Protocol: Requirements from Implementation
Apply this protocol when deriving requirements from an existing codebase.
The goal is to produce a structured requirements document that captures
what the implementation provides — not how it provides it. Execute all
phases in order.
## Phase 1: API Surface Enumeration
Systematically catalog every public-facing element of the codebase:
1. **Functions and entry points**: Signatures, parameters, return types,
error conditions. For each, note whether it is public API, internal,
or a convenience wrapper.
2. **Types and data structures**: Structs, enums, unions, typedefs.
Identify which are opaque (implementation detail) vs. transparent
(part of the API contract).
3. **Metaprogramming and indirection constructs** (if applicable):
Preprocessor macros (C/C++), decorators (Python), annotations (Java),
attribute macros (Rust), code generation. Expand representative
invocations to understand the actual behavior. Document parameters,
their types, and constraints.
4. **Constants and configuration surfaces**: Compile-time switches,
feature flags, tuning parameters. Identify which are user-facing
configuration vs. internal implementation constants.
5. **Error handling patterns**: How does the API report errors? Return
codes, errno, out-parameters, callbacks, exceptions? Catalog the
error space.
Produce a structured enumeration (table or list) before proceeding.
This becomes the completeness checklist for later phases.
## Phase 2: Behavioral Contract Extraction
For each API element identified in Phase 1:
1. **Preconditions**: What must be true before the caller invokes this?
Look for parameter validation, assertions, documented constraints,
and implicit assumptions (e.g., "pointer must not be NULL" even if
unchecked).
2. **Postconditions**: What is guaranteed after successful execution?
What state changes occur? What values are returned?
3. **Error behavior**: What happens on invalid input, resource exhaustion,
or concurrent access? Is the API fail-safe, fail-fast, or undefined?
4. **Side effects**: Does the function modify global state, allocate
memory the caller must free, register callbacks, or interact with
external systems?
5. **Ordering constraints**: Must certain functions be called before
others? Is there an initialization/teardown protocol?
6. **Thread safety**: Can this be called concurrently? From any thread?
What synchronization does the caller need to provide?
For each contract, cite the specific code evidence (file, line,
function) that establishes it.
## Phase 3: Essential vs. Incidental Classification
For every behavioral observation from Phase 2, classify it:
1. **Essential behavior**: Behavior that callers depend on and that
defines the API's value. This becomes a requirement.
- Test: "If this behavior changed, would existing correct callers break?"
- Test: "Is this behavior documented, tested, or part of the type
signature?"
2. **Incidental behavior**: Behavior that happens to be true in this
implementation but is not part of the contract.
- Test: "Could a correct reimplementation reasonably behave differently?"
- Test: "Is this an optimization, ordering artifact, or implementation
convenience?"
3. **Ambiguous behavior**: Cannot be classified without domain knowledge
or explicit confirmation from stakeholders. Flag with `[AMBIGUOUS]`.
For ambiguous items, state the two interpretations and their implications
for requirements.
## Phase 4: Requirement Synthesis
Transform essential behaviors into structured requirements:
1. **Group by functional area**: Organize related behaviors into
requirement categories (e.g., initialization, data processing,
error handling, resource management).
2. **Write atomic requirements**: Each requirement captures exactly one
testable behavior using RFC 2119 keywords (MUST, SHOULD, MAY).
3. **Derive acceptance criteria**: For each requirement, define at least
one concrete, measurable test derived from the code's actual behavior.
Prefer criteria that can be validated against the existing
implementation as a reference oracle.
4. **Preserve semantic fidelity**: Requirements must faithfully represent
what the implementation does, even if the behavior seems suboptimal.
If behavior appears buggy but is established, note it as a requirement
and flag: `[REVIEW: may be a defect in the reference implementation]`.
5. **Capture non-functional characteristics**: Performance bounds,
resource usage patterns, concurrency guarantees, and platform
requirements observed in the implementation.
## Phase 5: Completeness and Gap Analysis
1. **Coverage check**: Cross-reference the requirements against the
API surface enumeration from Phase 1. Every public API element
MUST have at least one associated requirement. Flag any gaps.
2. **Undocumented behavior**: Identify behaviors observed in the code
that have no documentation, no tests, and no obvious purpose.
These may be bugs, deprecated features, or undocumented contracts.
Flag with `[UNDOCUMENTED]`.
3. **Missing error cases**: For each API element, verify that error
conditions are covered by requirements. Missing error handling
is a common gap.
4. **Cross-cutting concerns**: Verify that thread safety, resource
lifecycle, and error propagation requirements are captured as
cross-cutting requirements, not just per-function notes.
<!-- BEGIN ocserv extensions -->
## ocserv-Specific Extensions
The sections below extend the generic protocol with ocserv's three-process
architecture, vtable interfaces, IPC contracts, and documentation sources.
### Phase 1 — API Surface Enumeration (ocserv)
The primary API surfaces in ocserv are not library exports but internal module
contracts. Enumerate them in this order:
1. **Auth module vtable** (`src/sec-mod-auth.h`, `auth_mod_st`): Every field
in the vtable is a required callback. Document which callbacks are mandatory
vs. optional (NULL-safe) and what each is expected to do.
2. **IPC message types** (`src/ipc.proto`, `src/ctl.proto`): Each message is
an entry point. For each, enumerate: direction (who sends, who receives),
required fields, optional fields, and the expected response message type.
3. **Configuration struct fields** (`src/common-config.h`, `cfg_st`,
`perm_cfg_st`, per-module config structs): Identify which fields are
user-configurable (surfaced in `src/config.c` or `src/subconfig.c`) vs.
internally derived. User-configurable fields have documentation in
`doc/ocserv.8.md` and `doc/sample.config`.
4. **Log macros** (`src/log.h`): `mslog()` (main), `oclog()` (worker),
`seclog()` (sec-mod). Note which severity levels are in use; this defines
the diagnostic contract.
5. **Error codes** (`src/defs.h`, `cmd_request_t`, error code enums): Catalog
every return code used in IPC and authentication flows.
### Phase 2 — Behavioral Contract Extraction (ocserv)
Adapt the generic questions for ocserv's process model:
- **"Thread safety"** → **"Process safety"**: ocserv's workers are isolated
processes with no shared memory. State crossing a process boundary MUST go
through IPC. If a function is called in multiple processes, its behavior in
each must be specified separately.
- **Talloc ownership** is the primary precondition to establish for every
allocation-returning function:
- Who is the talloc parent context?
- Is ownership transferred to the caller, or retained by the subsystem?
- Can the allocation outlive the talloc context passed to the function?
- Does the memory cross a process boundary? (If yes, it must be serialized
via protobuf — a raw talloc pointer is meaningless in another process.)
- **GnuTLS memory**: For functions that interact with GnuTLS, identify whether
returned memory must be freed with `gnutls_free()` rather than `talloc_free()`.
This is a separate ownership domain.
- **IPC ordering constraints**: For multi-message exchanges (e.g.,
`SEC_AUTH_INIT``SEC_AUTH_REP``SEC_AUTH_CONT``SEC_AUTH_REP`), the
ordering is a precondition. Document the full exchange sequence for each
operation, referencing `doc/design.md`.
- **Error behavior in the worker**: Workers run under seccomp. Any function
that attempts a system call not in the worker's seccomp whitelist will cause
the kernel to terminate the worker process (SIGKILL), not return an error.
This is an error behavior that MUST be captured as a requirement if the
function is called from worker context.
### Phase 3 — Essential vs. Incidental Classification (ocserv)
Use these additional tests before classifying behavior:
- **Documentation test**: If the behavior is described in `doc/ocserv.8.md`
or `doc/sample.config`, it is **essential** — it is the documented contract
with administrators. If the observed behavior contradicts the documentation,
flag it as: `[REVIEW: contradicts doc/ocserv.8.md — code or doc must change]`.
- **AnyConnect compatibility test**: If the behavior is related to the
CSTP/HTTSP protocol exchange, check `doc/README-cisco-svc.md`. Behaviors
that preserve AnyConnect client compatibility are **essential** even if not
documented in the man page.
- **Privilege boundary test**: Any behavior that enforces the three-process
privilege model (worker cannot access credentials, main cannot do auth) is
**essential** — it is a security invariant. Never classify these as incidental.
### Phase 4 — Requirement Synthesis (ocserv)
Group by these functional areas, annotating each requirement with its process:
| Category | Process(es) | Description |
|----------|-------------|-------------|
| `INIT` | main, sec-mod, worker | Startup, initialization, configuration loading |
| `AUTH` | sec-mod, worker (IPC) | Authentication flows, vtable callbacks |
| `ACCT` | sec-mod | Accounting start/stop, RADIUS, PAM acct |
| `SESSION` | sec-mod, main, worker | SID lifecycle, cookie issuance and validation |
| `IPC` | all | Message format, ordering, validation |
| `CFG` | main | Config parsing, reload behavior |
| `NET` | worker, main | TLS/DTLS handshake, IP allocation, routing |
| `SEC` | all | Seccomp, privilege drops, trust boundary enforcement |
| `ERR` | all | Error propagation, logging, client-visible error messages |
| `TEARDOWN` | all | Session cleanup, worker exit, talloc lifetime |
For `SEC` and `AUTH` categories, write the MUST NOT requirement before the
MUST requirement (negative contract precedes positive contract).
For `IPC` requirements, the acceptance criterion MUST reference specific
protobuf field names from `src/ipc.proto` or `src/ctl.proto`, not vague
descriptions.
### Phase 5 — Completeness and Gap Analysis (ocserv)
Additional gap checks specific to ocserv:
- **Vtable gap**: For every `auth_mod_st` vtable field, confirm a requirement
covers the expected behavior and the NULL-safety contract. A NULL callback
that the caller does not check is an undocumented crash path — flag it.
- **IPC field coverage**: For every field in each protobuf message, confirm
a requirement covers how the receiver handles it when missing (proto3
defaults to zero/empty) and what range of values is valid.
- **Config ↔ code gap**: For every field in the config struct visible in
`src/common-config.h`, confirm it appears in `doc/ocserv.8.md`. Undocumented
fields are either dead code or `[UNDOCUMENTED]` contracts.
- **Reload coverage**: For every configuration option, confirm whether a
requirement covers its behavior on `SIGHUP`. Non-reloadable options must
have a requirement stating that the value is fixed at startup.
- **Seccomp coverage**: For every syscall made from worker context, confirm
it is in the seccomp whitelist. Functions that reach the worker path through
indirect calls (callbacks, GnuTLS internals) are the most common gap.
<!-- END ocserv extensions -->
@@ -0,0 +1,306 @@
<!-- SPDX-License-Identifier: MIT -->
<!-- Copyright (c) PromptKit Contributors -->
---
name: requirements-reconciliation
type: reasoning
description: >
Systematic protocol for reconciling multiple requirements documents
from different sources (RFCs, implementations, specifications) into
a unified requirements document. Aligns requirements across sources,
classifies compatibility, and documents conflicts with resolution
options for human decision-making.
applicable_to:
- reconcile-requirements
---
# Protocol: Requirements Reconciliation
Apply this protocol when merging requirements extracted from multiple
sources — RFCs, implementations, specifications — into a single unified
requirements document. All sources are treated as equal inputs; no
source is inherently authoritative. The goal is to produce a "most
compatible" specification that documents what is universal, what is
majority practice, where sources diverge, and what is unique to a
single source.
## Phase 1: Source Inventory
Catalog the input requirements documents.
1. **For each source document**, record:
- Source name and origin (e.g., "RFC 9293", "Linux TCP stack",
"FreeBSD TCP stack", "Windows TCP stack")
- Total requirement count
- REQ-ID scheme used
- Keyword strength distribution (count of MUST, SHOULD, MAY)
- Categories/sections covered
2. **Assess coverage overlap**: Which functional areas do all sources
cover? Which are covered by only a subset? Build a preliminary
coverage matrix:
| Functional Area | Source 1 | Source 2 | Source 3 | ... |
|-----------------|----------|----------|----------|-----|
| Connection setup | ✓ | ✓ | ✓ | |
| Data transfer | ✓ | ✓ | ✓ | |
| Congestion control | ✓ | ✓ | ○ | |
Use ✓ for covered, ○ for partially covered, ✗ for absent.
## Phase 2: Requirement Alignment
Map requirements across sources to identify equivalences.
1. **For each requirement in each source**, find corresponding
requirements in the other sources. Match by:
- **Behavioral equivalence**: The requirements describe the same
behavior, possibly in different words.
- **Functional area + condition**: Requirements in the same
functional area with the same triggering condition.
- **State machine correspondence**: Requirements about the same
state, transition, or event.
Do NOT match by keyword or surface text similarity alone — two
requirements can use similar words but specify different behaviors.
2. **Build an alignment table**: Each row represents a single behavior
or constraint. Use temporary alignment IDs (U-001, U-002, ...) for
working reference — these will be replaced with final unified
REQ-IDs in Phase 5. Columns show how each source addresses it:
| Alignment ID | Behavior | Source 1 | Source 2 | Source 3 | ... |
|--------------|----------|----------|----------|----------|-----|
| U-001 | SYN retransmit timeout | REQ-TCP-034-012 (MUST, 3s) | LINUX-CONN-007 (MUST, 1s) | BSD-CONN-004 (MUST, 3s) | |
3. **Flag unmatched requirements**: Requirements that exist in only
one source and have no equivalent in any other source. These are
candidates for the Extension compatibility class.
## Phase 3: Compatibility Classification
For each aligned behavior (each row in the alignment table):
1. **Compare keyword strength** across sources:
- Do all sources agree on MUST/SHOULD/MAY?
- Does one source say MUST while another says SHOULD?
- Does any source omit this behavior entirely?
2. **Compare specified values** across sources:
- Do all sources agree on thresholds, timeouts, sizes?
- Where values differ, what is the range?
3. **Assign a compatibility class**:
- **UNIVERSAL**: All sources specify this behavior with the same
keyword strength and compatible values. This is safe to include
as-is in the unified spec with the agreed keyword.
- **MAJORITY**: Most sources (>50%) agree, but one or more diverge.
Include in the unified spec with the majority keyword. Document
which sources diverge and how.
- **DIVERGENT**: Sources actively disagree — different keyword
strengths, different values, or contradictory behaviors. Include
in the unified spec with all variants documented. Do NOT pick a
winner — the consumer must decide based on their use case.
- **EXTENSION**: Only one source specifies this behavior. Include
as MAY in the unified spec. Note which source defines it and
why it may or may not be desirable for interoperability.
4. **Record the classification rationale**: For each non-UNIVERSAL
requirement, briefly explain why it is not universal and what the
specific differences are.
## Phase 4: Conflict Analysis
For DIVERGENT requirements, perform deeper analysis:
1. **Categorize the conflict**:
- **Value disagreement**: Same behavior, different parameters
(e.g., timeout 1s vs. 3s). Document the range across sources.
- **Strength disagreement**: Same behavior, different keyword
(e.g., MUST vs. SHOULD). May indicate different risk
assessments.
- **Behavioral disagreement**: Different behaviors for the same
condition (e.g., "close connection" vs. "send reset"). These
are true conflicts requiring human resolution.
- **Presence disagreement**: One source requires behavior another
explicitly prohibits. These are the most dangerous conflicts.
2. **Assess interoperability impact**: For each conflict, answer:
- If an implementation follows source A's behavior and
communicates with an implementation following source B's
behavior, what happens?
- Is the result a failure, a degraded experience, or transparent?
3. **Suggest resolution options** (but do NOT pick one):
- Most conservative (strictest keyword, tightest value)
- Most permissive (loosest keyword, widest value)
- Most interoperable (the choice that causes fewest failures
when communicating with other implementations)
## Phase 5: Unified Specification Assembly
Produce the unified requirements document.
1. **Assign unified REQ-IDs**: Use the tag and scheme provided by the
template (e.g., `REQ-<TAG>-<CAT>-<NNN>` where `<TAG>` is the
user-provided unified tag).
2. **For each unified requirement**, include:
- The unified REQ-ID and requirement text
- **Compatibility class**: UNIVERSAL / MAJORITY / DIVERGENT /
EXTENSION
- **Keyword strength**: The unified keyword (for UNIVERSAL and
MAJORITY) or all source keywords (for DIVERGENT)
- **Source mapping**: Which source requirements map to this
unified requirement (REQ-IDs from each source)
- **Acceptance criteria**: Derived from the source with the most
specific criteria, or synthesized from multiple sources
- **Divergence notes** (for non-UNIVERSAL): What differs and why
3. **Group by category**: Use functional area categories consistent
across sources (e.g., CONNECTION, DATA_TRANSFER, CONGESTION,
TEARDOWN, ERROR, SECURITY).
4. **Produce a reconciliation summary**:
- Total unified requirements
- Count by compatibility class
- Count by keyword strength
- List of DIVERGENT requirements requiring human resolution
- List of EXTENSION requirements for review
## Phase 6: Interoperability Assessment
Produce an overall assessment of cross-source compatibility.
1. **Compatibility score**: % of requirements that are UNIVERSAL.
2. **Risk areas**: Functional areas with the highest concentration
of DIVERGENT requirements.
3. **Interoperability hotspots**: Specific behaviors where
implementations will conflict if they follow different sources.
4. **Recommendations**: Which DIVERGENT requirements are highest
priority for resolution and why.
<!-- BEGIN ocserv extensions -->
## ocserv-Specific Extensions
The sections below extend the generic protocol for the sources and functional
areas most relevant to ocserv: OpenConnect protocol, Cisco AnyConnect client
behavior, relevant IETF RFCs, and the ocserv implementation itself.
### Phase 1 — Source Inventory (ocserv)
The standard sources for ocserv protocol reconciliation are:
| Source ID | Origin | Normative weight |
|-----------|--------|-----------------|
| `OC-PROTO` | OpenConnect protocol documentation and `libopenconnect` implementation | Primary interoperability target |
| `AC-CLIENT` | Observed Cisco AnyConnect client behavior (see `doc/README-cisco-svc.md`) | Must not break; divergence must be flagged |
| `RFC-TLS` | RFC 8446 (TLS 1.3) and RFC 5246 (TLS 1.2) | Normative for TLS channel |
| `RFC-DTLS` | RFC 9147 (DTLS 1.3) and RFC 6347 (DTLS 1.2) | Normative for DTLS data channel |
| `OCSERV` | ocserv implementation (`src/`) | Current behavior; may extend or diverge from specs |
When reconciling, read `doc/README-cisco-svc.md` before any other source —
it documents known AnyConnect deviations from the OpenConnect protocol that
ocserv already accommodates.
Functional areas for the coverage matrix:
| Functional Area | OC-PROTO | AC-CLIENT | RFC-TLS | RFC-DTLS | OCSERV |
|-----------------|----------|-----------|---------|----------|--------|
| TLS channel setup | | | | | |
| DTLS channel setup | | | | | |
| CSTP auth exchange | | | | | |
| Cookie / session resumption | | | | | |
| IP/route configuration push | | | | | |
| Keepalive / dead-peer detection | | | | | |
| Session teardown | | | | | |
### Phase 2 — Requirement Alignment (ocserv)
When matching across sources, use these alignment anchors:
- **CSTP header fields**: Match by header name (e.g., `X-CSTP-MTU`,
`X-CSTP-DPD`). Differences in casing or allowed values are a DIVERGENT
signal.
- **HTTP exchange sequence**: Match by phase (TLS handshake → HTTP GET/CONNECT
→ auth exchange → tunnel establishment). A requirement about "step N" in one
source must be matched against the same protocol step, not the same HTTP
method.
- **TLS/DTLS parameters**: Match by parameter class (cipher, version, extension).
Different allowed ranges across sources are typically MAJORITY or DIVERGENT.
- **Timeout and keepalive values**: Match by semantic role (DPD interval,
cookie lifetime, reconnect window). Numeric differences are DIVERGENT with
value disagreement.
Flag unmatched `OCSERV` requirements as `[EXTENSION: ocserv-only]` — these
represent ocserv behaviors that extend the protocol (e.g., `occtl` management
interface, cgroup-based accounting, per-group config). They are not
interoperability risks but should be documented as extensions.
### Phase 3 — Compatibility Classification (ocserv)
Interpretation of compatibility classes in the ocserv context:
- **UNIVERSAL**: Safe to implement without concern for client or protocol
compatibility. Core TLS handshake behavior, standard RFC MUST requirements.
- **MAJORITY**: Implement the majority behavior as the default. If `AC-CLIENT`
is in the majority, the behavior is safe for AnyConnect compatibility.
If `AC-CLIENT` is the diverging source, flag as `[COMPAT-RISK: AnyConnect]`.
- **DIVERGENT**: Do NOT silently pick one behavior. Present all variants to
the maintainer. Behaviors where `AC-CLIENT` diverges from `OC-PROTO` or
RFCs are the most common DIVERGENT class in ocserv and require explicit
documentation in `doc/README-cisco-svc.md`.
- **EXTENSION**: Behaviors found only in `OCSERV`. These are ocserv-specific
features (management socket, virtual hosting, per-group routing) or
accommodations for specific client quirks. They carry no interoperability
risk with standard clients but must be documented in `doc/ocserv.8.md`.
### Phase 4 — Conflict Analysis (ocserv)
For DIVERGENT requirements, apply this additional assessment:
- **AnyConnect breakage risk**: If an implementation following `OC-PROTO` or
the RFC would break an AnyConnect client, the conflict is `[COMPAT-CRITICAL]`.
These conflicts must be escalated to the maintainer before any code change.
- **OpenConnect client compatibility**: If a behavior would break the
`openconnect` reference client used in tests (`tests/common.sh`), it is
a test infrastructure risk in addition to a protocol risk.
- **Security downgrade risk**: Conflicts where one source requires a weaker
TLS version, weaker cipher, or looser certificate validation must be
classified as `[SEC-RISK]` regardless of which source is the majority.
The most conservative (strictest) option is the only acceptable default.
Resolution option format for ocserv:
- **Most interoperable**: The choice that preserves both AnyConnect and
OpenConnect client compatibility.
- **Most RFC-compliant**: The choice that strictly follows the IETF RFC.
- **Current ocserv behavior**: What `OCSERV` currently does (baseline).
### Phase 5 — Unified Specification Assembly (ocserv)
Use these category tags in unified REQ-IDs:
| Tag | Description |
|-----|-------------|
| `CONN` | TLS/DTLS connection establishment |
| `AUTH` | Authentication exchange (CSTP auth headers, certificate validation) |
| `SESSION` | Cookie issuance, session resumption, roaming |
| `DATA` | Data channel (CSTP, DTLS packet framing, MTU, compression) |
| `CTRL` | Keepalive, DPD, disconnect signaling |
| `CFG` | IP/route/DNS configuration push to client |
| `COMPAT` | AnyConnect-specific behaviors that deviate from OC-PROTO |
| `SEC` | Security properties (cipher requirements, certificate validation) |
| `EXT` | ocserv extensions not present in OC-PROTO or client behavior |
For every `COMPAT` requirement, add a note referencing `doc/README-cisco-svc.md`
if the behavior is already documented there, or flag it for addition if not.
<!-- END ocserv extensions -->