feat(ITC-WP-0016): establish PracticePattern language
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a025c2-407a-7a32-b40a-f37a52f03f62
This commit is contained in:
parent
5e2435aaf9
commit
149d2ced70
27 changed files with 1119 additions and 99 deletions
267
infospace/patterns/InterfaceDeprecationStrangler.md
Normal file
267
infospace/patterns/InterfaceDeprecationStrangler.md
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
---
|
||||
id: practice-pattern/interface-deprecation-strangler
|
||||
title: InterfaceDeprecationStrangler
|
||||
type: practice-pattern
|
||||
scheme: practice-pattern/0.1
|
||||
status: active
|
||||
version: "0.1"
|
||||
summary: Replace an interface gradually while metering legacy use, guiding callers, and gating removal on evidence.
|
||||
aliases:
|
||||
- Metered Interface Strangler
|
||||
- Evidence-Gated Interface Deprecation
|
||||
uses:
|
||||
- model/governance
|
||||
- model/observability
|
||||
- model/devsecops
|
||||
related_patterns: []
|
||||
known_uses:
|
||||
- state-hub-workstream-to-workplan-transition
|
||||
---
|
||||
|
||||
# InterfaceDeprecationStrangler
|
||||
|
||||
## Intent
|
||||
|
||||
Phase out an old interface without guessing whether callers have migrated:
|
||||
introduce and verify its successor, make deprecation visible to callers, meter
|
||||
legacy use, progressively restrict the old behavior, and remove its final
|
||||
tombstone only when evidence satisfies an explicit retirement policy.
|
||||
|
||||
## Context
|
||||
|
||||
Use this pattern when a service, library, event stream, command, file format, or
|
||||
other integration surface must evolve while some callers may still depend on
|
||||
the old interface. Caller inventory is incomplete, release cycles are not
|
||||
coordinated, or removal has enough operational risk that absence of complaints
|
||||
is insufficient evidence.
|
||||
|
||||
The old and new interfaces may coexist briefly, or the old interface may
|
||||
already reject requests while still receiving attempts.
|
||||
|
||||
## Problem
|
||||
|
||||
An interface cannot safely remain forever, but deleting it on a planned date
|
||||
can break unknown callers. Keeping it indefinitely also has a cost: duplicated
|
||||
logic, ambiguity, security exposure, testing burden, and pressure to keep
|
||||
building on an obsolete contract.
|
||||
|
||||
A published deprecation notice alone proves neither that callers received it
|
||||
nor that they migrated. Raw request totals alone are also ambiguous: a request
|
||||
successfully served by compatibility code is different from an attempt rejected
|
||||
by a retired endpoint.
|
||||
|
||||
## Forces
|
||||
|
||||
- Callers need enough continuity to migrate without synchronized releases.
|
||||
- Maintainers need a bounded path to removal rather than permanent dual support.
|
||||
- Unknown callers cannot be coordinated directly until telemetry identifies
|
||||
them.
|
||||
- Caller guidance must be available at the point of use, not only in release
|
||||
notes.
|
||||
- Privacy and security constrain how caller identity and request data are
|
||||
recorded.
|
||||
- Infrequent but important callers can be absent from a short review window.
|
||||
- A replacement that exists but has not been verified is not a safe successor.
|
||||
- Once behavior returns a terminal response, attempted use still matters even
|
||||
though no legacy work was successfully performed.
|
||||
|
||||
## Solution
|
||||
|
||||
Therefore, wrap the interface transition in an evidence-producing strangler:
|
||||
|
||||
1. Register the legacy interface, its owner, successor, lifecycle state, and
|
||||
applicable hold or retirement policy.
|
||||
2. Implement and verify the successor before restricting the legacy path.
|
||||
3. Instrument the legacy boundary and communicate deprecation plus an actionable
|
||||
successor reference on every use where the protocol permits it.
|
||||
4. Record privacy-bounded usage evidence with enough outcome information to
|
||||
distinguish served legacy traffic, redirects, terminal rejection, and
|
||||
failures.
|
||||
5. Move through explicit stages from compatibility to terminal retirement.
|
||||
6. Keep a lightweight metered tombstone after terminal retirement so late
|
||||
attempts reveal remaining callers.
|
||||
7. Remove the tombstone only after the configured evidence gate passes and no
|
||||
manual hold remains.
|
||||
|
||||
The meter and caller guidance are part of the interface lifecycle, not optional
|
||||
observability added after the fact.
|
||||
|
||||
## Structure
|
||||
|
||||
```text
|
||||
Caller
|
||||
-> Legacy Boundary
|
||||
-> deprecation and successor guidance
|
||||
-> outcome-aware usage meter
|
||||
-> compatibility implementation OR terminal response
|
||||
-> Successor Interface
|
||||
|
||||
Interface Registry
|
||||
-> owner + lifecycle + successor + verification + holds
|
||||
|
||||
Review Activity
|
||||
-> usage windows + last-seen + caller attribution + outcome
|
||||
-> migration action OR stage advance OR continued hold
|
||||
```
|
||||
|
||||
The registry carries policy and identity. The meter carries observations. The
|
||||
review activity turns both into a decision; it must not infer removal from a
|
||||
calendar date alone.
|
||||
|
||||
## Dynamics
|
||||
|
||||
### Stage 1 — Announce and observe
|
||||
|
||||
Serve the old behavior, emit protocol-appropriate deprecation and successor
|
||||
information, and establish a usage baseline. Contact attributable callers.
|
||||
|
||||
### Stage 2 — Migrate and narrow
|
||||
|
||||
Move owned callers to the successor. Stop adding capabilities to the legacy
|
||||
surface. Narrow compatibility where doing so is reversible and observable.
|
||||
|
||||
### Stage 3 — Retire behavior, retain the tombstone
|
||||
|
||||
Return an explicit terminal result such as HTTP `410 Gone`, a typed CLI error,
|
||||
or a rejected event subject. Continue returning successor guidance and metering
|
||||
attempts.
|
||||
|
||||
At this stage a count means attempted use of a retired interface, not successful
|
||||
legacy traffic. Dashboards and evidence must preserve that distinction.
|
||||
|
||||
### Stage 4 — Remove the tombstone
|
||||
|
||||
Remove routing and instrumentation only after the successor is verified, no
|
||||
hold remains, and the evidence policy's quiet period has elapsed. Preserve the
|
||||
registry history and decision evidence.
|
||||
|
||||
Any new use can stop or reverse a stage transition when the cost of doing so is
|
||||
lower than breaking the caller.
|
||||
|
||||
## Invariants
|
||||
|
||||
1. Every legacy interface has an owner and an actionable successor reference.
|
||||
2. The successor is verified before legacy behavior is terminally retired.
|
||||
3. Caller-facing deprecation information travels on the legacy interaction
|
||||
where the protocol supports it.
|
||||
4. Metering failure does not silently turn absence of evidence into evidence of
|
||||
absence.
|
||||
5. Successful legacy service and rejected post-retirement attempts are not
|
||||
reported as the same outcome.
|
||||
6. A manual hold prevents automatic stage advancement.
|
||||
7. Quiet periods account for expected caller cadence and historical volume.
|
||||
8. Irreversible removal has retained evidence, rationale, and rollback or
|
||||
recovery guidance appropriate to its risk.
|
||||
9. Telemetry does not capture credentials or unnecessary request payloads.
|
||||
|
||||
## Evidence
|
||||
|
||||
The practice should produce:
|
||||
|
||||
- a registry record with interface identity, owner, successor, lifecycle state,
|
||||
replacement verification, and holds;
|
||||
- usage totals and bounded review windows;
|
||||
- last-seen time and, where allowed, tenant/user/component or equivalent caller
|
||||
attribution;
|
||||
- request outcome or an unambiguous derivation from the interface lifecycle
|
||||
stage;
|
||||
- evidence that owned callers use the successor;
|
||||
- the retirement threshold and its result; and
|
||||
- the decision that advanced, paused, or reversed the transition.
|
||||
|
||||
Quiet-window policy should reflect use cadence. A high-volume interface that
|
||||
has been quiet for one week may require a longer last-seen threshold than an
|
||||
interface that was used once. Evidence should say why an interface is or is not
|
||||
a retirement candidate rather than emitting only a boolean.
|
||||
|
||||
## Consequences
|
||||
|
||||
The organization gains a repeatable migration language, direct discovery of
|
||||
unknown callers, and an evidence-backed point at which compatibility can end.
|
||||
Late use becomes actionable information instead of a surprise outage.
|
||||
|
||||
The cost is temporary duplicate surface area, registry and telemetry storage,
|
||||
review ownership, privacy design, and discipline around outcome semantics. A
|
||||
tombstone has operating cost, but it is much smaller and safer than preserving
|
||||
the full legacy implementation.
|
||||
|
||||
## Failure Modes
|
||||
|
||||
- **NoticeOnly:** publish a deprecation date without observing real use.
|
||||
- **MeterWithoutMeaning:** count requests without distinguishing served traffic
|
||||
from rejected attempts.
|
||||
- **PermanentCompatibility:** meter forever but never define stage gates.
|
||||
- **CalendarRemoval:** delete on a date despite contrary usage evidence.
|
||||
- **UnverifiedSuccessor:** retire the old path because a replacement merely
|
||||
exists.
|
||||
- **SilentTombstone:** return a terminal response without successor guidance.
|
||||
- **TelemetryBlindness:** treat a broken meter as a quiet interface.
|
||||
- **IdentityOverreach:** collect payloads or personal data when coarse component
|
||||
attribution would suffice.
|
||||
- **ShortWindowConfidence:** miss monthly or quarterly callers by using only a
|
||||
short quiet window.
|
||||
|
||||
## When Not to Use
|
||||
|
||||
Do not use the full pattern for an interface that was never released, has a
|
||||
complete and controlled caller set that can be changed atomically, or must be
|
||||
disabled immediately because continued exposure is an unacceptable security or
|
||||
safety risk. In the last case, retire first and use the metered tombstone and
|
||||
recovery guidance only where they do not preserve the vulnerability.
|
||||
|
||||
## Known Uses
|
||||
|
||||
### State Hub workstream-to-workplan transition
|
||||
|
||||
State Hub replaced legacy `workstream` REST terminology with `workplan`
|
||||
interfaces. Its legacy registry records interface identity, owner, replacement,
|
||||
verification, holds, and usage buckets. Legacy responses carry deprecation,
|
||||
sunset, replacement, and successor-link metadata.
|
||||
|
||||
`GET /workstreams/{workstream_id}` is at Stage 3: it returns `410 Gone`, directs
|
||||
the caller to `GET /workplans/{workplan_id}`, and records the attempt. The weekly
|
||||
review therefore exposes remaining callers without implying that the retired
|
||||
request succeeded. Retirement candidacy combines review-window traffic,
|
||||
last-seen time, replacement verification, manual holds, and a quiet-period
|
||||
ladder scaled by historical call volume.
|
||||
|
||||
Implementation references:
|
||||
|
||||
- repository: `state-hub`;
|
||||
- compatibility behavior: `api/services/legacy_compat.py`;
|
||||
- known route: `api/routers/workstreams.py`;
|
||||
- evidence policy: `api/services/legacy_meter.py`; and
|
||||
- operational description: `docs/workplan-terminology-transition.md`.
|
||||
|
||||
### Arc Nexus adoption
|
||||
|
||||
`arc-nexus` declares this PracticePattern as its policy for phasing out old
|
||||
architecture registry interfaces. This is an adoption decision, not yet a
|
||||
second implementation proof.
|
||||
|
||||
## Related Patterns
|
||||
|
||||
This pattern is a specialized strangler migration with an explicit evidence and
|
||||
governance loop. Future related patterns may separate successor verification,
|
||||
compatibility facades, evidence-gated removal, and consumer migration campaigns
|
||||
once repeated uses justify independent names.
|
||||
|
||||
## Adoption Checklist
|
||||
|
||||
- [ ] Give the legacy and successor interfaces stable identities.
|
||||
- [ ] Assign an owner and verify the successor.
|
||||
- [ ] Define lifecycle stages, holds, and outcome semantics.
|
||||
- [ ] Add caller-facing deprecation and successor guidance.
|
||||
- [ ] Meter privacy-bounded usage and test meter failure behavior.
|
||||
- [ ] Establish a review cadence and quiet-period policy.
|
||||
- [ ] Migrate known callers and investigate unknown attribution.
|
||||
- [ ] Retire behavior while retaining a metered tombstone.
|
||||
- [ ] Confirm that evidence distinguishes attempted from successful use.
|
||||
- [ ] Record the removal decision and preserve lifecycle history.
|
||||
|
||||
## Evolution
|
||||
|
||||
Version 0.1 generalizes the practice proven by State Hub's terminology
|
||||
transition. The next useful evidence is a second implementation in a different
|
||||
interface style, such as events, CLI commands, or schemas, to test which outcome
|
||||
and successor fields should become structured canon concepts.
|
||||
154
infospace/patterns/PracticePatternScheme.md
Normal file
154
infospace/patterns/PracticePatternScheme.md
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
---
|
||||
id: scheme/practice-pattern
|
||||
title: PracticePattern Scheme
|
||||
type: practice-pattern-scheme
|
||||
status: active
|
||||
version: "0.1"
|
||||
summary: A common Markdown contract for naming and sharing recurring socio-technical practices.
|
||||
owned_concepts:
|
||||
- PracticePattern
|
||||
- PatternLanguage
|
||||
---
|
||||
|
||||
# PracticePattern Scheme
|
||||
|
||||
## Intent
|
||||
|
||||
Give people and agents a stable language for recurring ways of working. A
|
||||
PracticePattern names a proven or proposed arrangement of actions, roles,
|
||||
interfaces, feedback, and evidence that resolves a recurring tension in a
|
||||
particular context.
|
||||
|
||||
This scheme is inspired by Christopher Alexander's pattern-language method:
|
||||
each pattern connects a context and a system of forces to a reusable solution,
|
||||
describes the resulting consequences, and participates in a language of related
|
||||
patterns. It adapts that idea for software, operations, architecture, and
|
||||
governance practices; it does not copy a building pattern or require a fixed
|
||||
implementation technology.
|
||||
|
||||
## Artifact identity
|
||||
|
||||
A PracticePattern is a Markdown canon artifact with:
|
||||
|
||||
- a speakable canonical name in UpperCamelCase, such as
|
||||
`InterfaceDeprecationStrangler`;
|
||||
- a stable artifact ID, `practice-pattern/<kebab-case-name>`;
|
||||
- `type: practice-pattern`;
|
||||
- `scheme: practice-pattern/0.1`;
|
||||
- an independently versioned pattern body;
|
||||
- a lifecycle status; and
|
||||
- registration in `infospace/artifacts/index.yaml`.
|
||||
|
||||
The canonical name is part of the shared language. Aliases help discovery but
|
||||
must not silently replace it.
|
||||
|
||||
## Required frontmatter
|
||||
|
||||
```yaml
|
||||
---
|
||||
id: practice-pattern/example-name
|
||||
title: ExampleName
|
||||
type: practice-pattern
|
||||
scheme: practice-pattern/0.1
|
||||
status: candidate
|
||||
version: "0.1"
|
||||
summary: One sentence stating the practical move.
|
||||
aliases: []
|
||||
uses: []
|
||||
related_patterns: []
|
||||
known_uses: []
|
||||
---
|
||||
```
|
||||
|
||||
The machine-readable contract is
|
||||
`infospace/schemas/practice-pattern.schema.yaml`.
|
||||
|
||||
### Lifecycle
|
||||
|
||||
| Status | Meaning |
|
||||
| --- | --- |
|
||||
| `draft` | The problem and solution are still being shaped. |
|
||||
| `candidate` | Coherent enough for trial, but known uses are limited. |
|
||||
| `active` | Supported by at least one concrete known use and suitable for reuse. |
|
||||
| `deprecated` | Superseded or discouraged; relationship to its successor is explicit. |
|
||||
| `retired` | Preserved for provenance but no longer recommended. |
|
||||
|
||||
Version and lifecycle are separate. A wording clarification can change the
|
||||
version without changing lifecycle; evidence from a new known use can promote a
|
||||
candidate to active.
|
||||
|
||||
## Required body sections
|
||||
|
||||
Every PracticePattern must contain these second-level headings:
|
||||
|
||||
1. `Intent` — the practical move in compact form.
|
||||
2. `Context` — the conditions in which the pattern applies.
|
||||
3. `Problem` — the recurring failure or tension.
|
||||
4. `Forces` — pressures that make a simplistic solution insufficient.
|
||||
5. `Solution` — the stable arrangement, written as a directive.
|
||||
6. `Dynamics` — the sequence or feedback loop through which it operates.
|
||||
7. `Invariants` — properties an implementation must preserve.
|
||||
8. `Evidence` — observations needed to decide, advance, or stop.
|
||||
9. `Consequences` — benefits, costs, and new responsibilities.
|
||||
10. `Known Uses` — concrete applications and their maturity.
|
||||
|
||||
These headings are validated by the canon. Their contents may use diagrams,
|
||||
tables, checklists, or prose.
|
||||
|
||||
## Recommended body sections
|
||||
|
||||
Use these where they improve adoption:
|
||||
|
||||
- `Structure` for roles, components, and relationships;
|
||||
- `Failure Modes` for common incomplete or unsafe implementations;
|
||||
- `When Not to Use` for boundary conditions;
|
||||
- `Adoption Checklist` for a practical start and completion test;
|
||||
- `Related Patterns` for the surrounding pattern language; and
|
||||
- `Evolution` for provenance, open questions, and version history.
|
||||
|
||||
## Writing rules
|
||||
|
||||
1. Name a recurring practice, not a product feature or one repository's
|
||||
implementation.
|
||||
2. State the problem before prescribing the solution.
|
||||
3. Make forces genuinely competing; a list of requirements is not a force
|
||||
analysis.
|
||||
4. Write the solution as a stable arrangement and keep technology-specific
|
||||
examples in Known Uses.
|
||||
5. Separate invariants from optional implementation techniques.
|
||||
6. State which evidence changes the practice's state or permits an irreversible
|
||||
move.
|
||||
7. Name costs and failure modes as directly as benefits.
|
||||
8. A known use must identify what was actually observed; intended adoption is
|
||||
not implementation evidence.
|
||||
9. Relationships must use stable artifact IDs when the related artifact is in
|
||||
the canon.
|
||||
10. Pattern conformance means preserving the invariants, not copying a known
|
||||
use literally.
|
||||
|
||||
## Relationship vocabulary
|
||||
|
||||
PracticePatterns form a language rather than an isolated catalog. Use:
|
||||
|
||||
- `uses` when this pattern depends on another canon artifact or mechanism;
|
||||
- `related_patterns` for complementary, alternative, predecessor, or successor
|
||||
PracticePatterns, with the relation explained in the body;
|
||||
- artifact-index `conforms_to` to point to this scheme;
|
||||
- artifact-index `uses`, `requires`, or `implements` for graph-visible canon
|
||||
relationships; and
|
||||
- Known Uses to point outward to concrete consumer implementations.
|
||||
|
||||
## Conformance
|
||||
|
||||
A file conforms to PracticePattern v0.1 when its frontmatter validates against
|
||||
the schema, all required body sections are present, its artifact index entry has
|
||||
`kind: practice-pattern`, and every internal relationship target resolves.
|
||||
|
||||
Conformance does not imply that the practice is active or recommended. That is
|
||||
expressed by lifecycle status and known-use evidence.
|
||||
|
||||
## Evolution
|
||||
|
||||
Version 0.1 establishes the smallest useful shared contract. Later versions may
|
||||
add structured force, role, evidence, and known-use records after several
|
||||
patterns demonstrate which structure is genuinely reusable.
|
||||
|
|
@ -1,3 +1,19 @@
|
|||
# Patterns
|
||||
|
||||
Reusable canon patterns live here.
|
||||
|
||||
## PracticePattern language
|
||||
|
||||
PracticePatterns give recurring socio-technical practices stable, speakable
|
||||
names. They follow the Alexander-inspired, Markdown-first contract in
|
||||
[PracticePatternScheme](PracticePatternScheme.md). The current scheme is v0.1;
|
||||
frontmatter is described by
|
||||
[`practice-pattern.schema.yaml`](../schemas/practice-pattern.schema.yaml).
|
||||
|
||||
| PracticePattern | Status | Purpose |
|
||||
| --- | --- | --- |
|
||||
| [InterfaceDeprecationStrangler](InterfaceDeprecationStrangler.md) | active | Phase out an interface through caller guidance, usage evidence, staged retirement, and an evidence-gated removal. |
|
||||
|
||||
The older [Intent Scope Purposes Pattern](intent-scope-purposes.md) predates the
|
||||
PracticePattern v0.1 contract. It remains a candidate canon pattern and can be
|
||||
migrated when its next substantive revision is made.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue