diff --git a/docs/oss/attribution.md b/docs/oss/attribution.md index bfa5237..3a025ff 100644 --- a/docs/oss/attribution.md +++ b/docs/oss/attribution.md @@ -3,7 +3,8 @@ ## Standard Repository Policies Material: `docs/policy/oss.md`, `docs/policy/meta.md`, -`docs/policy/agents.md`, `docs/policy/documentation.md`, `AGENTS.md`, and the +`docs/policy/agents.md`, `docs/policy/documentation.md`, +`docs/policy/architecture.md`, `docs/policy/testing.md`, `AGENTS.md`, and the Policy Reading Guide section of `docs/development.md`, adapted for this repository. diff --git a/docs/policy/architecture.md b/docs/policy/architecture.md index def19b4..7003aa7 100644 --- a/docs/policy/architecture.md +++ b/docs/policy/architecture.md @@ -1,147 +1,109 @@ # Architecture Policy -**Base Policy Version:** 1.1 +**Base Policy Version:** 1.3 -**Last Updated:** 2026-09-26 +**Last Updated**: 2026-09-28 + +**Upstream Source:** https://gitea.maximumdirect.net/eric/policy/src/commit/d84a38ebab26f048cafbe59a2246700c35d29843/docs/policy/architecture.md ## Purpose And Ownership -This policy defines Scriptorium's purpose, responsibility and dependency -boundaries, established invariants, and non-goals. Concrete component inventory -and implementation mechanics belong in [internal documentation](../internal/overview.md); -public behavior belongs in its canonical contracts. +The adopted policy defines the application's purpose and the architectural +constraints contributors must follow. It owns system boundaries, responsibility +and dependency rules, established invariants, and explicit non-goals. -Adopted constraints govern future development without implying that every -capability they could govern exists or is planned. Keep proposed structure and -implementation status in roadmaps, and decision rationale in ADRs. Acceptance -of a decision is not proof of implementation. Do not turn incidental choices -into architectural invariants. +Describe the concrete package inventory and implementation mechanics in internal +documentation. Link to canonical public contracts for their exact behavior and +to ADRs for decision rationale. -## System Shape +## Architectural Approach -Scriptorium is an executable application with four command entry paths: CLI -`run`, CLI `render`, CLI `inspect`, and the HTTP service started by `serve`. -The `inspect` command has prompt and profile modes. Scriptorium does not expose -a reusable root Go package. +Hexagonal architecture is strongly recommended, including encapsulating external +integrations and APIs within internal adapters. Keep domain and application +logic independent of external integration details, and make dependency direction +clear in the adopted policy. -The application consumes +Implement that separation with proportionate, idiomatic code. Choose interfaces +and package layout to serve the application's actual boundaries. Use adapters +for collaborators with external integration responsibilities. + +## Adopted Constraints And Implemented Structure + +Architectural constraints govern current and future development. Record +implemented structure accurately, proposals and implementation status in the +roadmap, and significant decisions and rationale in ADRs. Describe a target +structure as implemented when its changes land. + +Constraints must reflect deliberately selected requirements and decisions. +Do not promote incidental implementation choices into architectural invariants. + +## Scriptorium's Purpose And System Shape + +Scriptorium is an executable application with CLI `run`, `render`, +`inspect`, and `config` command families and an HTTP service started by +`serve`. It offers simple, request-independent execution of predefined +prompts, not a reusable Scriptorium root Go API or a workflow framework. +The [internal overview](../internal/overview.md) owns the concrete package +inventory; [adapter internals](../internal/adapters.md) and +[source internals](../internal/sources.md) own implementation mechanics. + +## Framework And Application Boundaries + +Scriptorium consumes [Promptkit v0.11.1](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.11.1/docs/consumers/pkg-promptkit.md) -through its supported root package. Promptkit owns prompt execution, -preparation, source formats, built-in profiles, model-client behavior, and -validation. Scriptorium owns application configuration, executable adapters, -prepared-run and definition-inspection presentation, process behavior, and HTTP -deployment policy. +through its supported public root package. Promptkit owns prompt execution, +preparation, prompt and profile formats, built-in profiles, model-client +behavior, validation, and framework defaults. Scriptorium owns application +configuration, executable CLI and HTTP adapters, prepared-run and +definition-inspection presentation, process behavior, and HTTP deployment +policy. The [format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.11.1/docs/formats.md) +and [outbound integration contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.11.1/docs/integrations/openai-compatible-chat.md) +remain Promptkit's contracts. -Scriptorium also consumes ConfigKit v0.4.1 for application configuration -decoding, resolution, and validation flow. Scriptorium owns its application -schema, defaults, normalization, validation rules, source selection, and CLI -flag mapping; ConfigKit does not own Promptkit framework sources or HTTP -artifact containment. +Scriptorium uses ConfigKit v0.4.1 for strict application YAML decoding, +resolution, and validation flow. Scriptorium retains its application schema, +defaults, normalization, validation rules, source selection, and CLI override +mapping. ConfigKit does not own Promptkit framework sources or HTTP artifact +containment. The [configuration contract](../config.md) owns externally +observable configuration behavior. -The concrete package inventory is maintained in the -[internal overview](../internal/overview.md). +Application code may import Promptkit's public root package, but not its +`internal` packages or catalog modules. It must not recreate the removed +Scriptorium framework facade or former framework package families. Use +consumer-owned interfaces only where substitution at an adapter boundary is +needed. Omitted framework settings pass as zero values so Promptkit applies +its own defaults. Cross-project changes land and release in Promptkit before +Scriptorium adopts its tagged dependency; do not commit Go workspaces, local +replacements, vendored Promptkit source, or unpublished dependency assumptions. +The repository's architecture guard protects these import and removal +boundaries. Adapter separation does not require an interface for every type, +extra wrappers, or a fixed directory tree. -As established by [ADR 0004](../adr/0004-definition-boundary.md), Scriptorium -aims to support the complete set of features in valid Promptkit prompt and -profile definitions for its selected upstream version. Promptkit remains the -canonical parser and validator. Library-only features are considered -individually against the simple predefined-prompt execution model. +## Definition Support And Request State -Maintain adapter boundaries with proportionate, idiomatic code. This approach -does not require an interface for every type, additional wrappers, or a fixed -directory tree for integrations that do not exist. +As decided in [ADR 0004](../adr/0004-definition-boundary.md), Scriptorium aims +to support the complete set of features in valid Promptkit prompt and profile +definitions for its selected upstream version. Promptkit remains the canonical +parser and validator. Library-only features are considered individually +against Scriptorium's simple predefined-prompt execution model. -## Dependency Direction - -```text -cmd/scriptorium - | - v -CLI and HTTP adapters, configuration, defaults, and formatting - | - v -Promptkit (execution) and ConfigKit (application configuration) -``` - -- Retained application packages may import Promptkit's root package. -- They must not import Promptkit `internal` packages. -- They must not import Promptkit catalog modules directly. -- They must not import the removed Scriptorium root facade or recreate former - framework package families. -- Adapter-owned interfaces use Promptkit public values when a consumer-side - substitution boundary is needed. -- Scriptorium passes omitted framework settings as zero values so Promptkit - applies its own defaults. - -The repository architecture guard enforces these import and removal -invariants. - -Cross-project changes land and release in Promptkit before Scriptorium adopts -the tagged dependency. Do not commit Go workspaces, local replacements, -vendored Promptkit implementation, or unpublished dependency assumptions. - -## Retained Boundaries - -- `internal/adapter/cli` owns commands, flags, configuration precedence, - process streams, output files, summaries, and exit codes. -- `internal/adapter/http` owns routes, strict JSON DTOs, size limits, response - mapping, status mapping, and the restricted artifact reader. -- `internal/config` owns discovery and Scriptorium's application definition; - ConfigKit owns strict YAML decoding and the load/override pipeline. -- `internal/defaults` owns Scriptorium application and HTTP defaults only. -- `internal/format` owns deterministic prepared-run and definition-inspection - text and JSON presentation. -- Promptkit owns framework orchestration and contracts. Its - [format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.11.1/docs/formats.md) - and - [outbound integration contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.11.1/docs/integrations/openai-compatible-chat.md) - are canonical. - -## HTTP Artifact Security Boundary - -Ordinary CLI file loading is provided by Promptkit. Scriptorium's HTTP adapter -injects a restricted `promptkit.ArtifactReader` for inbound HTTP requests. -That reader denies file references without an artifact root, enforces the -configured byte limit, and applies Scriptorium's lexical root-containment rule. -The operating system still follows symlinks after the lexical check. - -This boundary handles untrusted request references under the documented -deployment model; it is not a filesystem sandbox. Defending against a -privileged actor concurrently modifying the host filesystem is outside the -adopted scope, not a claim that such activity cannot occur. Do not infer -additional defenses or guarantees from hypothetical threats; raise unsettled -scope decisions under the [agent policy](agents.md). - -The [HTTP API](../api.md) owns observable request outcomes, and -[operations](../operations.md) owns deployment permissions and root selection. - -## State, Errors, And Secrets - -Scriptorium has no durable run-state store, checkpoint, cache, or resume -mechanism. Recovery is a new request after correcting inputs, configuration, or -environment. - -Each request is self-contained from the caller's perspective, without -conversation or workflow state retained from completed requests. This does -not mean the process is internally stateless. Shared engines, backend capacity -and queue accounting, in-flight coordination, cancellation, and server -lifecycle resources are permitted and must be shared where necessary to -enforce configured backend limits across concurrent requests. Such state must -be concurrency-safe and does not create a durable user-workflow contract. - -Adapters map Promptkit public error identities into CLI exits or HTTP statuses -without classifying by message text. Raw API keys are not accepted in -Scriptorium configuration, CLI arguments, or HTTP payloads, and resolved +External YAML and JSON decoding remains strict. Adapters map external values +through Promptkit public requests and results without taking over framework +orchestration. Explicit numeric request overrides preserve presence, including +zero. Adapters map Promptkit public error identities to CLI exits or HTTP +statuses without classifying by message text. Raw API keys are not accepted +in Scriptorium configuration, CLI arguments, or HTTP payloads, and resolved secrets must not be emitted. -## Architectural Invariants - -- External YAML and JSON decoding remains strict. -- CLI and HTTP behavior remains presentation and transport logic rather than - framework orchestration. -- Explicit numeric request overrides preserve presence, including zero. -- HTTP artifact containment and byte limits remain Scriptorium policy. -- No application package depends on Promptkit implementation packages. +Each execution request is self-contained from the caller's perspective; no +conversation or workflow state is retained from completed requests. This +does not preclude process-scoped operational state. A server shares its +Promptkit engine, backend registry, capacity admission and queue accounting +across relevant concurrent requests so configured backend limits cannot be +bypassed by per-request construction. In-flight coordination, cancellation, +and server lifecycle state must be concurrency-safe. None of this creates a +durable workflow, checkpoint, cache, or resume contract; recovery is a new +request after correcting inputs, configuration, or environment. ## Non-Goals @@ -153,5 +115,19 @@ secrets must not be emitted. - Do not add durable workflow, archive, or resume behavior. - Do not add application-managed prompt modification, follow-up message flows, conversation management, or multi-step workflow orchestration. +## Trust Boundaries And Threat Scope -Work that is not implemented belongs in `docs/roadmap/`. +Ordinary CLI file loading belongs to Promptkit. For untrusted inbound HTTP +artifact references, Scriptorium injects a restricted +`promptkit.ArtifactReader`. It denies file references without an artifact +root, applies the configured byte limit, and enforces lexical root containment. +The operating system follows symlinks after that lexical check. This is not a +filesystem sandbox or a defense against a privileged actor concurrently +modifying the host filesystem; that threat is outside the adopted scope. +Do not infer stronger defenses from hypothetical threats. Raise unsettled +scope decisions under the [agent policy](agents.md). + +The [HTTP API](../api.md) owns observable request outcomes, the +[configuration contract](../config.md) owns credential supply, and +[operations](../operations.md) owns deployment permissions and root selection. +The [source internals](../internal/sources.md) describe reader mechanics. diff --git a/docs/policy/testing.md b/docs/policy/testing.md index fe021a5..d305c12 100644 --- a/docs/policy/testing.md +++ b/docs/policy/testing.md @@ -1,14 +1,16 @@ # Testing Policy -**Base Policy Version:** 1.1 +**Base Policy Version:** 1.3 -**Last Updated:** 2026-09-26 +**Last Updated**: 2026-09-28 + +**Upstream Source:** https://gitea.maximumdirect.net/eric/policy/src/commit/d84a38ebab26f048cafbe59a2246700c35d29843/docs/policy/testing.md ## Purpose Our tests exist to make **incorrect changes expensive and correct changes cheap**. -We do not optimize for test count, line coverage, exhaustive isolation, or the fewest possible tests. We optimize for sufficient confidence in important behavior while imposing as little unnecessary friction as possible on future development. +We optimize for sufficient confidence in important behavior while minimizing friction on future development. ## Every test has a cost @@ -22,9 +24,9 @@ Evaluate that tradeoff at two levels: 1. **Per test:** What realistic defect does this test detect, how consequential would that defect be, and is that protection worth the test's lifetime cost? 2. **Across the suite:** Does this collection provide materially more confidence than a smaller, simpler suite would? -Some friction is intentional. Tests should make dangerous changes—such as breaking compatibility, corrupting data, violating security boundaries, or reintroducing subtle bugs—require deliberate review. They should not make ordinary internal changes needlessly expensive. +Some friction is intentional. Tests should make dangerous changes—such as breaking compatibility, corrupting data, violating security boundaries, or reintroducing subtle bugs—require deliberate review. Keep ordinary internal changes inexpensive. -The cost of a test is not a reason to omit testing by default. Do not cite maintenance cost abstractly. When omitting a plausible test, be able to state why the protected failure is low-risk, already covered, obvious, reversible, or cheaper to detect elsewhere. For consequential, subtle, or difficult-to-observe behavior, the presumption should favor testing. +Evaluate maintenance cost against the specific failure being protected. When omitting a plausible test, be able to state why the protected failure is low-risk, already covered, obvious, reversible, or cheaper to detect elsewhere. For consequential, subtle, or difficult-to-observe behavior, the presumption should favor testing. ## Default testing style @@ -56,7 +58,7 @@ To the extent the following features are present in the application, prioritize 6. Previously observed or plausible regressions. 7. Representative integration and end-to-end workflows. -A package-level contract is behavior relied upon by another package or major collaborator, not every observable detail of a package implementation. +A package-level contract comprises behavior relied upon by another package or major collaborator. Choose tests for requested behavior and established contracts. Tests must not introduce new restrictions, guarantees, or threat scenarios merely because they @@ -75,14 +77,8 @@ Do not add tests merely because a function, branch, or line exists. Do not add a ## Choose the right test boundary -Test through the narrowest stable boundary that expresses the behavior clearly. - -For application configuration, ConfigKit owns exhaustive YAML grammar, -source traversal, import/overlay composition, provenance, and inspection -renderer tests. Scriptorium tests its selected definition, source discovery, -CLI override presence, command prerequisites, runtime conversion, credential -boundary, and representative execution/inspection workflows with the tagged -library. Do not copy the upstream parser test matrix into this repository. +Choose the narrowest stable boundary that expresses the behavior clearly and +provides durable confidence with minimal incidental coupling. This is often the package API, but it may instead be: @@ -90,22 +86,15 @@ This is often the package API, but it may instead be: - a package-level operation when several internal collaborators jointly produce the behavior; or - a larger integration boundary when correctness emerges from interaction with a real dependency. -Do not force all behavior through oversized end-to-end tests. Do not test every private helper merely because it exists. Choose the boundary that gives durable confidence with the least incidental coupling. - ## Test behavior, not implementation -A test should protect a decision, contract, or invariant. A test must not memorialize the current implementation. +A test should protect a selected decision, contract, or invariant. -A test is suspect when its main purpose is to detect that someone: +A test is suspect when it primarily detects changes to private constants or +helpers, equivalent operation ordering, incidental formatting, equivalent +algorithms, or internal structure that preserves behavior. -- changed an internal constant; -- renamed or split a private helper; -- reordered equivalent internal operations; -- changed incidental formatting; -- replaced one correct algorithm with another; or -- refactored internal object structure without changing behavior. - -Refactoring should normally require no test edits unless the refactored structure is itself part of the contract. +Behavioral tests should normally remain stable through internal refactoring that preserves the contract. ## Expected effects of different changes @@ -122,7 +111,7 @@ A test failing is not the same as a test needing to be edited. Many tests may co ## Separate mechanism from policy -Configurable thresholds and defaults must not be duplicated throughout the test suite. +Derive expectations from test-controlled configuration and relationships. For this example, assume the selected contract rejects a request to start more processes than a configured limit. Do not encode its production default indirectly: @@ -158,33 +147,52 @@ limit solely to reproduce this example. The production default should be tested exactly only when its literal value is itself a public, operational, safety, protocol, or compatibility requirement. -Apply the same rule to limits, timeouts, capacities, retry counts, and ranges: test relationships and behavior, not duplicated literals. +Apply the same rule to limits, timeouts, capacities, retry counts, and ranges: test relationships and behavior. For established concurrency limits, distinguish these behaviors where the contract requires them: 1. **Configuration handling:** values are accepted or rejected according to the selected contract. 2. **Runtime enforcement:** observed peak concurrency never exceeds the configured limit. -Use a test-controlled limit and measure the behavior relative to that limit. Do not merely assert today's default value. +Use a test-controlled limit and measure the behavior relative to that limit. -## Avoid semantic duplication across layers +## Assign each behavior a test owner -Each behavior should have a clear test owner. +Where these layers exist, assign ownership as follows: -- Configuration tests own application YAML, strict decoding, discovery, - precedence, and application defaults. -- CLI tests own argument mapping, streams, summaries, exit behavior, and - representative command workflows. -- HTTP tests own DTOs, strict decoding, limits, status mapping, and restricted - artifact policy. -- Formatter tests own prepared-run and definition-inspection text and JSON - presentation. -- Architecture tests own dependency direction and removal invariants. +- Parser tests own parsing cases. +- Validator tests own validation rules. +- Domain tests own transformations and invariants. +- Adapter tests own external integration behavior. +- Orchestrator tests own coordination and failure propagation. +- CLI tests own argument and configuration mapping. +- End-to-end tests prove that representative assembled workflows work. + +Give each layer its distinct responsibility and keep expectation updates localized to the contract being changed. + +## Scriptorium Test Ownership + +- Application configuration tests own Scriptorium's definition, strict + decoding at its boundary, source discovery and selection, explicit CLI + override presence, application defaults, runtime conversion, and safe + diagnostics. ConfigKit owns exhaustive YAML grammar, source traversal, + import and overlay composition, provenance, and inspection renderers. +- CLI tests own argument mapping, streams, output, exit behavior, and + representative run, render, inspect, serve, and config workflows. +- HTTP tests own DTO decoding, transport limits, status and error mapping, + restricted artifact reading, and representative server workflows. +- Formatting tests own prepared-run and definition-inspection text and JSON + presentation. Architecture guards own dependency direction and removed + framework-package boundaries. - Promptkit owns framework parsing, orchestration, validation, profiles, and - model-client behavior. Scriptorium's definition compatibility fixtures protect - its adapter plumbing without duplicating the upstream format contract. + model-client behavior. Scriptorium's definition and execution fixtures + protect adoption through its public adapter boundary without duplicating + Promptkit's exhaustive format matrix. -Higher-level tests should not repeat every lower-level case. A single intentional policy change should not require unrelated edits across many test files. +HTTP lexical containment, size limits, and shared engine and backend capacity +across concurrent requests merit focused adapter coverage because violations +cross a security or concurrency boundary. Choose cases by realistic risk +rather than a coverage quota or a duplicated upstream matrix. ## Use test doubles deliberately @@ -205,12 +213,9 @@ Mocks are appropriate when the contract includes facts such as: - an expensive API is called no more than once; or - a security audit event is emitted. -Do not use mocks merely to isolate every object or reproduce the implementation's call graph. - ## Go-specific guidance -Select techniques according to the behavior and risk being tested. The following -are options, not a checklist that every package or application must satisfy: +Select techniques by behavior and risk: - table-driven tests for meaningful behavioral categories and boundaries; - `t.TempDir()` for real filesystem behavior; @@ -220,55 +225,48 @@ are options, not a checklist that every package or application must satisfy: - integration tests where correctness depends on component interaction; and - a small number of representative end-to-end tests when assembled workflows expose meaningful risks not adequately covered at narrower boundaries. -Avoid exact error-string assertions unless the wording is itself contractual. Prefer `errors.Is`, `errors.As`, typed errors, or structured error fields. +Prefer `errors.Is`, `errors.As`, typed errors, or structured error fields. Use exact error-wording assertions only when the wording is contractual. -At CLI boundaries, prefer exit classifications, structured output, and the smallest stable semantic fragment needed to identify the error. Do not snapshot complete diagnostic wording unless it is contractual. +At CLI boundaries, prefer exit classifications, structured output, and the smallest stable semantic fragment needed to identify the error. Use complete diagnostic snapshots only when the wording is contractual. Golden-file updates must require an explicit local flag. CI must not update golden files automatically, and reviewers must inspect the semantic diff before accepting an update. -Keep tests readable and direct. Test helpers and fixture frameworks must earn their own maintenance cost; do not build elaborate test infrastructure for small or isolated needs. +Keep tests readable and direct. Size test helpers and fixture frameworks to the maintenance benefit they provide. ## Coverage -Coverage is a diagnostic, not a target. +Use coverage to locate untested critical branches and unexpectedly weak packages. Evaluate test quality through meaningful behavioral protection and choose coverage according to risk. -Use it to find untested critical branches and unexpectedly weak packages. Do not write low-value tests solely to increase a percentage, and do not infer test quality from coverage alone. - -Security-sensitive HTTP containment and external mappings may warrant denser -coverage than straightforward process wiring. Uneven coverage is acceptable -when it reflects risk. +Pure domain logic will often warrant higher coverage than CLI wiring or external adapters. Uneven coverage is acceptable when it reflects risk. ## Regression tests A bug fix should normally include a regression test that fails before the fix and passes afterward. -Retain the test when the defect could realistically recur and its consequences justify the ongoing cost. Prefer the narrowest durable test of the violated contract or invariant; do not preserve accidental implementation details from the original bug. +Retain the test when the defect could realistically recur and its consequences justify the ongoing cost. Prefer the narrowest durable test of the violated contract or invariant. -Not every historical bug requires a permanent test. If the underlying design has made recurrence impossible, the test has become redundant, or a stronger invariant test now subsumes it, remove or consolidate it. +Remove or consolidate a test when the underlying design has made recurrence impossible, its protection is redundant, or a stronger invariant test subsumes it. ## Deleting or rewriting tests -Tests are maintained code, not permanent historical artifacts. - -Delete or rewrite a test when its maintenance cost exceeds the confidence it provides. +Delete or rewrite tests when maintenance cost exceeds their continuing +protective value. Strong candidates include tests that: - require updates after harmless internal changes; -- directly assert private constants without protecting a real contract; -- duplicate the same policy across several layers; +- assert incidental private constants or snapshot large amounts of incidental output; - verify mock choreography rather than outcomes; -- snapshot large amounts of incidental output; -- test trivial private helpers already exercised through stable package behavior; -- protect risks already covered more effectively elsewhere; +- duplicate policy across layers, retest trivial helpers covered by package + behavior, or protect risks covered more effectively elsewhere; - are flaky, misleading, obsolete, or disproportionately expensive to diagnose; or - no longer correspond to a plausible failure mode. -Several brittle tests may encode one genuine requirement. Replace them with one durable behavior-level or invariant test rather than preserving all of them. +Several brittle tests may encode one genuine requirement. Consolidate them into one durable behavior-level or invariant test. ## Reviewing a proposed test -Use the following questions when the value, boundary, or durability of a proposed test is not self-evident. Significant test additions should be reviewable against them, but written answers are not required for every routine test. +Use the following questions when a proposed test needs closer evaluation. Significant test additions should be reviewable against them; written answers are optional for routine tests. 1. Which requested behavior or established contract does it protect, and what realistic defect would violate it? 2. How likely and consequential is that defect, and is it already protected elsewhere? @@ -282,10 +280,9 @@ A test suite is sufficient when: - important requested behavior and established contracts are protected against realistic, consequential failures; - boundaries and component interactions have coverage where they introduce meaningful risks not protected elsewhere; -- failures provide useful signal rather than redundant noise; -- legitimate internal changes usually do not require test edits; and +- failures provide useful, distinct signals; +- tests usually remain stable through legitimate internal changes; and - additional tests would mostly repeat existing protection or preserve inconsequential implementation details. -Sufficiency is a risk judgment, not a coverage percentage, test count, or required -mix of testing techniques. Reassess it as the application, its users, and the -consequences of failure evolve. +Reassess sufficiency as the application, its users, and the consequences of +failure evolve. diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 9b52811..02d834e 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -169,7 +169,10 @@ Generic language differences from upstream are eliminated, not rephrased. ## Stage 3: Adopt Architecture And Testing With Narrow Local Decisions -**Status: Pending.** +**Status: Complete.** The three shared architecture sections and the common +testing text match the pinned source. Local architecture decisions were checked +against the accepted ADRs and internal guides; focused test ownership and the +expanded attribution scope were reviewed without changing application code. Files: `docs/policy/architecture.md`, `docs/policy/testing.md`, policy attribution entry, and focused internal docs only if moving existing