Decision Log

This file records choices that materially affect framework behavior or the experiment. Superseded decisions remain in version control and are linked from their replacements.

D-001: Treat the complete framework as the primary intervention

  • Date: 2026-07-23
  • Status: accepted

The primary comparison evaluates capsules, declarations, indexes, and CLI tools as one treatment. The hypothesis concerns their combined maintenance workflow.

Rejected: claim a causal effect for each primitive from the two-arm comparison. That would require ablations and substantially more runs. Ablations remain optional follow-up experiments with separate preregistration.

D-002: Use a strong plain-TypeScript control

  • Date: 2026-07-23
  • Status: accepted

The control will use strict TypeScript, idiomatic explicit dependency injection, a mature runtime-validation library, feature or layered organization, concise documentation, and good tests. It will not use this framework’s generated index or CLI in the primary comparison.

Rejected: force both arms to use the framework’s schema code or fragment the control into excessive files. Either would contaminate the control or make it artificially weak.

D-003: TypeScript values are authoritative; indexes are projections

  • Date: 2026-07-23
  • Status: accepted

Operations, features, ports, events, and invariants are declared as imported TypeScript values. The compiler derives a deterministic JSON index from source. The runtime does not depend on this generated file.

Rejected: YAML manifests as the source of truth, decorator metadata, filesystem auto-discovery, and generated operation source. These add a second authority or hidden registration behavior.

D-004: No global registry or implicit lifecycle

  • Date: 2026-07-23
  • Status: accepted

Applications explicitly pass features and adapter bindings to createApplication. Events, invariants, and transactions have explicit call or adapter boundaries.

Rejected: module-import side effects, service locators, automatic event-bus subscription, and invisible post-command invariant execution. They reduce local reasonability even when convenient.

D-005: Declare capability-picked port operations

  • Date: 2026-07-23
  • Status: accepted for Phase 2 experiment

An operation maps local effect names to individual typed port operations. Its execution context exposes only those capabilities. Effect IDs and categories are derived from the port-operation descriptors, avoiding a second string list that can drift.

Rejected: inject every application port into every command, or declare effect strings separately from injected functions. The first makes undeclared access easy; the second duplicates authority.

This API remains subject to usability and compile-time experiments before the example application is frozen. A change must preserve explicitness and be logged.

D-006: Expected domain failures use typed outcomes

  • Date: 2026-07-23
  • Status: accepted for Phase 2 experiment

Commands return a discriminated Outcome whose error variants are inferred from the declared error-schema map. Unexpected exceptions represent defects.

Rejected: unchecked thrown strings/classes for expected failures. They do not make the complete error contract visible to callers or the index.

D-007: Effect control uses types, runtime guards, and source checks

  • Date: 2026-07-23
  • Status: accepted

The execution context limits typed access; dispatcher wrappers validate active operation declarations; an architecture checker rejects known ambient I/O and nondeterminism in domain files.

Rejected: describe those checks as a security sandbox. Ordinary JavaScript and dependencies can evade static policy. The framework promises architectural enforcement for cooperative application code, not hostile-code isolation.

D-008: Invariants are executable but explicitly invoked

  • Date: 2026-07-23
  • Status: accepted for initial implementation

Invariants are named pure predicates over validated evidence. Operations declare which invariants they preserve, and tests or explicit application code execute them. verify follows these links.

Rejected: automatically execute all related invariants after every command. Evidence acquisition could hide I/O and produce unpredictable runtime cost.

D-009: Conservative verification widens on uncertainty

  • Date: 2026-07-23
  • Status: accepted

affected explains its dependency closure. verify uses narrow type and test scopes only when project and dependency information prove them safe. Shared configuration, core types, dynamic imports, stale metadata, and unresolved edges widen verification to the application or workspace.

Rejected: always run only directly named tests. A fast but unsound verifier would improve benchmark efficiency by hiding regressions.

D-010: Use static source analysis for index generation

  • Date: 2026-07-23
  • Status: accepted for initial implementation

The compiler will use the TypeScript compiler API, accepting only statically resolvable stable metadata. Application code is not executed to build the index.

Rejected: import compiled application modules to inspect descriptors. Imports could perform arbitrary side effects and make generation depend on runtime environment.

If compiler-API complexity makes the declaration API unreadable, the design must be reconsidered rather than adding custom syntax.

D-011: Start with two applications, not three

  • Date: 2026-07-23
  • Status: accepted

The framework and plain implementations are sufficient for the first valid comparison. A conventional established-framework arm may be added only after behavioral equivalence and reliable telemetry exist.

Rejected: add the third arm during initial construction. It increases fixture, task, and repetition cost and could delay or weaken the primary experiment.

D-012: Lock primary result rules before implementation

  • Date: 2026-07-23
  • Status: accepted

The provisional win condition, token missingness rules, category-improvement definition, invalid-run rules, and repetitions are fixed in Phase 1. Any later change is a protocol amendment and separates cohorts when results may have been observed.

Rejected: tune thresholds or remove outliers after seeing favorable or unfavorable results.

D-013: Count all model context and keep correctness as a gate

  • Date: 2026-07-23
  • Status: accepted

Provider telemetry includes framework documentation, index output, and tool results supplied to the model. Cached input remains part of accounted token use. Failed runs retain their actual telemetry but are not assigned invented token penalties. Efficiency is analyzed among successes only after checking success non-inferiority.

Rejected: subtract framework context as a one-time cost, treat cached tokens as zero context, or combine correctness and tokens into a compensatory score.

D-014: Use npm workspaces and a small dependency surface

  • Date: 2026-07-23
  • Status: accepted

The workspace uses npm 11.13.0 workspaces, TypeScript 7.0.2 project references, ES modules, Node 24, and exact dependency versions in the lockfile. Runtime framework packages have no third-party runtime dependencies. Test/build-only dependencies include Vitest 4.1.10 and fast-check 4.9.0.

Rejected: a custom build system, monorepo orchestrator, or package manager requirement that does not materially serve the experiment. The installed toolchain was checked before implementation and through a clean rebuild.

D-015: Phase 1 produces design evidence only

  • Date: 2026-07-23
  • Status: accepted

No core framework code is written until the Phase 1 architecture, experimental protocol, confounders, and implementation plan have been presented. Phase 1 is validated through document consistency and explicit gate review rather than invented implementation tests.

D-016: Use TypeScript 7’s explicit unstable compiler API exports

  • Date: 2026-07-23
  • Status: accepted with compatibility risk

TypeScript 7.0.2 no longer exposes program and AST APIs from the package root. The compiler therefore imports the official typescript/unstable/sync and typescript/unstable/ast entry points. The dependency is pinned exactly and the scanner has fixture tests.

Rejected: execute compiled application modules to recover metadata, or pin an older compiler only to retain a familiar API. Executing application source would violate the source-analysis design and introduce environment-dependent effects. The unstable entry-point risk is tracked in LIMITATIONS.md.

D-017: Validate effect response schemas outside production hot paths

  • Date: 2026-07-23
  • Status: superseded by D-031 after the first real-agent UX audit

Adapter calls must always return the structural Outcome shape. Development and test modes additionally validate effect success/error payloads against their schemas. Production skips that second payload parse while operation input, output, domain errors, permissions, and emitted events remain validated.

Rejected: silently trust arbitrary non-Outcome adapter values in production. The runtime benchmark will measure whether always-on effect payload validation is affordable; this decision may be revisited before fixtures are frozen.

D-018: Share only the black-box commerce contract between study arms

  • Date: 2026-07-23
  • Status: accepted

The two example applications share public request/response types, route and error constants, and a reusable acceptance-suite factory. They do not share business services, validation schemas, repositories, ports, routing code, or domain implementations. The shared production entry point has no Vitest or framework dependency; test registration is a separate subpath export.

Rejected: share domain services to make equivalence easy. That would measure two wrappers around one implementation instead of framework versus plain TypeScript.

D-019: Make concurrent stock and duplicate handling observable correctness

  • Date: 2026-07-23
  • Status: accepted

The plain control serializes the payment-and-commit order section and commits state atomically. The framework application uses an explicit product reservation effect, releases on payment decline or failed commit, and atomically rejects duplicate storage writes. The shared suite requires one success for two concurrent orders against one stock unit and one success for concurrent duplicate customer/product creation.

Rejected: omit concurrency because the initial sequential suite passed. A framework efficiency result built on overselling or duplicate-success behavior would fail the correctness gate.

D-020: Use deterministic default example infrastructure

  • Date: 2026-07-23
  • Status: accepted

Both example factories default to a fixed 2030-01-01T00:00:00.000Z clock and monotonic order IDs. Tests inject their own clocks and IDs. Real time remains an adapter concern, but a deterministic default makes fixtures and differential diagnostics reproducible.

Rejected: let the plain control default to ambient time while the framework defaults to a constant. That produced an avoidable behavioral difference.

D-021: Authorize HTTP operations before transport input mapping

  • Date: 2026-07-23
  • Status: accepted after independent equivalence audit

The HTTP adapter resolves the route and principal, then checks the operation’s declared permissions before invoking route-specific path/body mapping. A denied request is represented as the same core-compatible RejectedDispatch shape used by normal dispatch and flows through the route’s response mapper. Core dispatch repeats authorization as defense in depth.

Rejected: rely only on core authorization after parsing the HTTP body. That made unauthorized malformed requests return validation details and differed from the plain control.

D-022: Keep shared production code symmetric and transport-only

  • Date: 2026-07-23
  • Status: accepted after independent equivalence audit

Both application arms import the same pure route, permission, status, envelope, and standard-error constants from shared-contract. Neither imports shared business services, repositories, schemas, commands, or domain logic. The acceptance runner remains a test-only subpath.

Rejected: allow only the framework arm to reuse shared transport constants. That could favor it in route, authorization, or error maintenance tasks for a reason unrelated to feature capsules or generated metadata.

D-023: Make creation claims and generated-ID compensation explicit

  • Date: 2026-07-23
  • Status: accepted after independent equivalence audit

Customer and product creation acquire an atomic per-ID claim before reading the clock, so a concurrent duplicate loser consumes no time. Both arms release a claim after construction failure. Order ID generators return an untrusted string; both arms trim and reject blank IDs, and the framework releases its stock reservation before returning the common internal-error response.

Rejected: rely on a final atomic insert after reading the clock, or encode an unchecked generator callback as if it could only return a branded ID. Both approaches hid observable failure behavior from the contract.

D-024: Freeze initial runtime and automated-DX budgets from smoke data

  • Date: 2026-07-23
  • Status: accepted before any agent-maintenance result was observed

The runtime executable was calibrated in explicit smoke mode on the recorded Apple M4 Max host (Node 24.16.0, npm 11.13.0, TypeScript 7.0.2). Thirty measured samples per fast/process metric produced framework medians of 28.4 ms cold start, 2.0 microseconds synthetic dispatch, 0.7/1.8 microseconds valid/invalid schema parsing, 46.4 ms index generation, and a 4.1 MB retained-RSS delta for 100 live systems. One-sample fresh-workspace engineering probes measured 0.51 s clean application build, 0.72 s full application type-check, and 0.96 s incremental framework verification. These are calibration observations, not hypothesis evidence.

Before confirmatory agent data, the following budgets are fixed for the frozen host class and repository scale:

  • framework cold-start median at most 100 ms and at most 2x the plain median;
  • framework dispatch p95 at most 100 microseconds and median at most 5x plain;
  • valid and invalid schema-validation p95 at most 100 microseconds and median at most 5x plain;
  • index-generation median at most 500 ms and p95 at most 1 second;
  • retained-RSS delta for 100 live framework systems at most 16 MiB;
  • clean build and full type-check medians at most 5 seconds and at most 2x plain;
  • localized incremental verification median at most 5 seconds and at most 2x the equivalent plain type-check-plus-test workflow; and
  • zero failed benchmark commands or critical architecture/security findings.

Automated-DX acceptability additionally requires all documented CLI commands to remain deterministic, no-overwrite scaffold behavior, strict type-checks, and a successful full hidden regression run. Human comprehension/editor ergonomics remain unmeasured and must be reported separately; these automated budgets do not establish that humans prefer the framework.

Rejected: tune budgets after seeing maintenance-run outcomes, use relative-only budgets where the plain operation is extremely small, or treat smoke timings as evidence for the primary hypothesis.

D-025: Freeze scheduling, analysis, and task time limits

  • Date: 2026-07-23
  • Status: superseded by D-027 before any confirmatory observation

The confirmatory run order is frozen in benchmarks/harness/config/confirmatory-schedule.v1.json. It contains 100 slots covering ten tasks, two arms, and five repetitions. The blocked-randomization seed was agentfw-commerce-v1-2026-07-23, the schedule structural hash was 63512f0c3cec1de88768ef813405485af948c2f74f9bc91b2e9cf947ae720199, and the schedule file hash was 08439ce6e6f756452a79eb1bcf5e4006554f5ee2133587f429f7b903f4305c1d.

Version-1 deterministic analysis does not bootstrap or otherwise sample, so it does not consume a random seed. agentfw-analysis-v1-2026-07-23 was reserved for a separately preregistered stochastic supplement; introducing such a supplement after viewing outcomes would be a protocol amendment, not part of the primary analysis.

Tasks 01 through 09 have a 1,800-second agent wall-clock limit. Task 10 is a narrow architecture-answer task and has a 900-second limit. Provisioning and hidden evaluation remain outside the agent limit as defined in the protocol.

Rejected: regenerate a convenient schedule, change time limits after observing which arm times out, or add bootstrap output opportunistically after inspecting the primary result.

D-026: Require operational proof before Phase 6

  • Date: 2026-07-23
  • Status: accepted

Phase 6 may start only from a clean immutable Git revision with production hidden-evaluator drivers and their hashes, an approved provider adapter with an immutable model/configuration identity, a frozen pricing and retention record, and explicit budget authorization. Every run must use a fresh model session in a runtime-verifiable killable OS sandbox under frozen network, host/container, dependency-cache, fixture-cohort, and provisioning policies.

The harness’s scripted and injected drivers validate mechanics only. They are permanently ineligible for confirmatory success. File-copy isolation or a declared sandbox label without runtime evidence does not satisfy this gate.

Rejected: treat an uncommitted snapshot, smoke adapter, caller assertion, or best-effort process timeout as sufficient evidence for the confirmatory study.

D-027: Name the framework Agentix and supersede the provisional freeze

  • Date: 2026-07-23
  • Status: accepted before any confirmatory observation

The framework’s public name is Agentix. The active package scope is @agentix/*, the CLI binary is agentix, the generated projection is .agentix/index.json, and benchmark/runtime protocol identifiers use the agentix prefix. The local Git origin is git@github.com:pewpewgogo/agentix.git. Scientific arm values and paths remain the generic framework and plain labels so branding does not alter analysis.

The rename changed 71 of the 140 provisional inventory sources and added one shared build helper, yielding a 141-file Agentix inventory. Because the repository had no Git HEAD and zero confirmatory observations, the provisional D-025 corpus and schedule were superseded in place rather than pooled with the Agentix study. The active identities are agentix-commerce-app-base and agentix-commerce-maintenance-v1; their refreshed base-inventory and corpus-lock SHA-256 values are respectively f2cc4306e5e29849b4f1f00230057b0a114b4b53a68653b8945ea63747d0e87c and 48deddc989e7dab69eeab9fa88759484531a3b424e771d6d2ec5560a40aef08e.

The active 100-slot schedule seed is agentix-commerce-v1-2026-07-23, its structural hash is f2141cd81018d3720b8783547274cac4e291a88bfd35cfbc6497149287258ba4, and its exact pretty-JSON file SHA-256 is d3b488cd9e600c7c083f04116bb4b7c576d945b6e297e0ebe50df922794448a6. The deterministic primary analysis remains seedless; agentix-analysis-v1-2026-07-23 is reserved only for the same separately preregistered stochastic supplement described in D-025. Task limits and all win conditions are unchanged.

Rejected: silently relabel old hashes as current, mix the provisional and Agentix corpus identities, rename the scientific arm values, or retain the old binary as an undocumented compatibility alias.

Remaining decisions required before the full benchmark

Exact tool versions are fixed in D-014, runtime and automated-DX budgets in D-024, and the current scheduling, analysis-seed policy, and task limits in D-025 as superseded by D-027. The following choices remain unresolved and must be frozen before any confirmatory run:

  • exact provider, immutable model version, reasoning configuration, and service tier;
  • host/container image and dependency-cache policy;
  • raw provider-payload retention/redaction policy; and
  • whether a separately preregistered ablation is affordable.

Phase 1 verification record

  • Date: 2026-07-23
  • Result: passed the documentation gate; implementation has not started

The relevant checks and exact results were:

for doc in docs/HYPOTHESIS.md docs/ARCHITECTURE.md docs/BENCHMARK_PROTOCOL.md docs/LIMITATIONS.md docs/DECISIONS.md; do test -s "$doc" || exit 1; done
exit 0; no output

git diff --check
exit 0; no output

rg -q 'five percentage points' docs/HYPOTHESIS.md && rg -q '20 percent' docs/HYPOTHESIS.md && rg -q 'seven of the ten' docs/HYPOTHESIS.md && rg -q '100 valid runs' docs/BENCHMARK_PROTOCOL.md
exit 0; no output

test -z "$(find . -path './.git' -prune -o -path './docs' -prune -o -type f -print)"
exit 0; no output

A separate in-memory Node check also confirmed all five required documents were non-empty, their fenced code blocks were balanced, and the fixed verdict and telemetry phrases were present. It reported:

phase-1-doc-check: PASS (5 required documents)

One combined-check attempt used path as the zsh loop variable. In zsh that special variable is tied to PATH, so subsequent git, rg, and find commands were not found. That attempt was discarded, the variable was corrected to doc, fail-fast mode was enabled, and all commands above were rerun.

There is no package manifest or executable source yet, so build, type-check, and runtime tests are not applicable in Phase 1. Their absence is a phase boundary, not evidence of implementation correctness.

Phase 2 verification record

  • Date: 2026-07-23
  • Result: passed the framework-primitives gate

The final clean integration check and exact result were:

npm install --ignore-scripts
changed 1 package; audited 66 packages; 0 vulnerabilities

npm run clean
exit 0

npm run build
exit 0

npm run typecheck
exit 0

npm test
17 test files passed; 77 tests passed

git diff --check
exit 0; no output

Manual CLI smoke checks ran the built binary against the compiler’s valid fixture:

node packages/cli/dist/bin.js inspect orders.create --root packages/compiler/test/fixtures/valid --json
exit 0; returned operation, effects, events, invariant, test, affected set, and verification plan

node packages/cli/dist/bin.js graph orders --root packages/compiler/test/fixtures/valid --format text
exit 0; returned dependency, operation, effect, event, invariant, and test edges

node packages/cli/dist/bin.js affected customers --root packages/compiler/test/fixtures/valid --json
exit 0; selected customers plus the dependent orders closure with reasons

node packages/cli/dist/bin.js scaffold feature audit-log --root packages/compiler/test/fixtures/valid --dry-run --json
exit 0; reported six files and performed no writes

Failures encountered and retained during the phase:

  • the first testing-package smoke could not load its project because the core project reference had not yet been created; the unchanged test path passed after the core skeleton landed;
  • one core test expected application assembly to reject a hostile query, but defineQuery correctly rejected it earlier; the test was corrected to assert the appropriate enforcement layer; and
  • root Vitest initially collected a scanner-only fixture named orders.test.ts; fixture discovery was isolated and the full suite was rerun cleanly.

Phase 3 and Phase 4 verification record

  • Date: 2026-07-23
  • Result: paired applications and behavioral-equivalence gate passed

The original clean verification was:

npm run clean
exit 0

npm run build
exit 0

npm run typecheck
exit 0

npm test
29 test files passed; 115 tests passed

npm run test:acceptance
10 test files passed; 33 tests passed across framework and plain applications

node packages/cli/dist/bin.js verify orders.create --root examples/framework-app --json
passed: true; typecheck status 0; test status 0; architecture diagnostics 0

node packages/cli/dist/bin.js inspect orders.create --root examples/framework-app --json
exit 0; all seven declared effects resolved to stable operation IDs and kinds

git diff --check
exit 0; no output

The generated framework-application index hash at this source state was:

sha256 7af0aba71ee1e923400cd0e871738063627c2d492a2935abfecc3a979b02980b

The suite includes reusable black-box scenarios, focused unit/invariant tests, compile-time tests, architecture checks, deterministic replay helpers, schema and invariant property tests, concurrent-order tests, and detached-state checks.

Failures found and corrected before the gate passed:

  • a Vitest alias matched the shared package root before its /acceptance subpath;
  • agentfw verify ran repository-root include globs from an application root and found no tests, so verification now prefers declared package scripts;
  • the compiler fixture used an impossible shorthand and the scanner did not resolve the real Port.operations.<key> API; both fixture and scanner were corrected;
  • differential probes found mismatched path-ID normalization, ambient versus fixed default time, concurrent duplicate successes, and framework overselling; these became shared regression checks or explicit fixes; and
  • order overflow and duplicate-ID paths now release framework reservations before returning an internal failure.

An independent equivalence audit then found authorization-before-body, generated-ID, shared-constant asymmetry, duplicate-clock, and malformed-path gaps. All five were converted to code fixes and shared or focused regression tests. The post-audit gate was:

npm install
up to date; audited 72 packages; 0 vulnerabilities

npm run typecheck
exit 0

npm run test:acceptance
11 test files passed; 40 tests passed across framework and plain applications

npm test --workspace @agentfw/adapters-http
3 test files passed; 16 tests passed

git diff --check
exit 0; no output

The expanded oracle checks unauthorized malformed and absent request bodies, blank generated order IDs with unchanged local state, malformed URI encoding, and exactly one clock read for each winning concurrent customer/product create. The earlier index hash and full-suite counts above describe the pre-audit source state and will be superseded by the final Phase 5 clean record.

Phase 5 verification record

  • Date: 2026-07-23
  • Result: engineering gate passed; confirmatory experiment not started

This record preserves the provisional pre-Agentix source state and hashes. It was superseded by the D-027 naming amendment before any confirmatory run.

The final local verification was:

npm install --ignore-scripts
up to date; audited 80 packages; 0 vulnerabilities

npm run clean
exit 0

npm run build
exit 0

npm run typecheck
exit 0

npm test
46 test files passed; 222 tests passed

npm run test:acceptance
11 test files passed; 41 tests passed

npm run test:phase5
16 test files passed; 97 tests passed

npm run benchmark:corpus:check
10 tasks; 20 arms; 140 inventory files; verified

npm run benchmark:harness:smoke
1 test file passed; 3 tests passed

All 20 task-arm fixtures materialized. An offline install, type-check, and application test run also passed for both task-05 arms. Repeated index generation was byte-identical with SHA-256 e9ca2a263a84b22f07e194bd914b457a8f27cfa136325584fc6640eb67fe45a2. The CLI inspection, graph, affected-set, verify, and no-write scaffold paths were exercised against the framework application.

Runtime smoke exercised diagnostic/no-process collection, two fresh isolated process builds, both-arm clean-build/full-type-check/incremental toolchain probes, and sealed create-only evidence publication. Disabled metric groups were recorded as unavailable rather than synthesized. Every smoke record is marked ineligible for confirmatory use.

Failures found and fixed during the gate included stale package-local Vitest discovery, an acceptance assertion that excluded a legitimate internal 500 response, a compiler file-discovery shortcut coupled to benchmark paths, a report-integrity check that incorrectly compared pre- and post-provisioning manifests, and harness classification that initially treated an agent-created prohibited workspace entry as invalid evidence instead of a valid failed run. The final independent audit additionally found and fixed a scalar cohort timeout that could not represent task 10’s shorter limit, writable source-linked runtime dependencies, and documented-but-unimplemented correction provenance. A timing-sensitive synthetic lifecycle test was stabilized without changing any frozen benchmark limit. Each fix is covered by the final suite or a focused regression test.

No external provider, paid API, full 100-slot experiment, deployment, package publication, or confirmatory observation occurred. The repository has no Git HEAD, production hidden drivers and operational sandbox evidence are absent, and the only valid framework verdict is INCONCLUSIVE.

Agentix naming verification record

  • Date: 2026-07-23
  • Result: Agentix identity and local engineering gate passed; confirmatory experiment not started

D-027 was applied across the public package scope, imports, CLI and benchmark binaries, generated-index directory, runtime/protocol identifiers, corpus identities, documentation, and local Git remote. Scientific arms remain the generic framework and plain values. The four remaining provisional-name strings in this document are preserved historical evidence from before D-027.

The final quiescent verification was:

npm ci --ignore-scripts
added 67 packages; audited 80 packages; 0 vulnerabilities

npm run clean
exit 0

npm run build
exit 0; all three declared CLI targets executable

npm run typecheck
exit 0

npm test
46 test files passed; 222 tests passed

npm run test:acceptance
11 test files passed; 41 tests passed

npm run test:phase5
16 test files passed; 97 tests passed

npm run benchmark:corpus:check
10 tasks; 20 arms; 141 inventory files; verified

npm run benchmark:harness:smoke
1 test file passed; 3 tests passed

npm test --workspace @agentix/core
5 test files passed; 28 tests passed

npm test --workspace @agentix/compiler
1 test file passed; 8 tests passed

npm test --workspace @agentix/cli
1 test file passed; 6 tests passed

All 20 Agentix task-arm fixtures materialized. Both task-05 arms passed an offline clean install, type-check, and application suite: 25 files/103 tests for the framework arm and 6 files/24 tests for the plain arm. Repeated index generation was byte-identical with SHA-256 e99d9ea8e50b205a2497f1cb08c3d5a5894f377b5b37fe269dbae659289ab8b2.

Direct invocation passed for agentix, agentix-benchmark-report, and agentix-runtime-benchmark. Final runtime smoke produced two bound fresh builds, 20 process samples, zero process-probe unavailable entries, six both-arm toolchain samples, and a sealed publication that re-read successfully. Every smoke result remained ineligible for confirmatory use.

The active schedule structural/file hashes are f2141cd81018d3720b8783547274cac4e291a88bfd35cfbc6497149287258ba4 and d3b488cd9e600c7c083f04116bb4b7c576d945b6e297e0ebe50df922794448a6. The final base-inventory/corpus-lock hashes are f2cc4306e5e29849b4f1f00230057b0a114b4b53a68653b8945ea63747d0e87c and 48deddc989e7dab69eeab9fa88759484531a3b424e771d6d2ec5560a40aef08e.

The local origin is git@github.com:pewpewgogo/agentix.git. No commit, push, provider call, deployment, publication, or confirmatory observation occurred.

D-028: Add a separate exploratory Agentix/Express/NestJS HTTP comparison

  • Date: 2026-07-23
  • Status: accepted before observing comparison results

The frozen Agentix-versus-plain runtime and agent-maintenance protocols remain unchanged. Express and NestJS are not assigned artificial equivalents for Agentix command dispatch, schema, generated-index, or incremental-verification metrics. Instead, a separate exploratory runner compares identical real loopback POST /echo endpoints on these exact stacks:

  • Agentix using its Node HTTP adapter;
  • Express 5.2.1;
  • NestJS 11.1.28 using its default Express adapter.

The run seed is agentix-http-frameworks-exploratory-v1-2026-07-23. The first full exploratory run uses 10 warmups, 100 measured valid requests, 100 measured invalid requests, and five fresh-child observations per stack. Every three-stack block contains each stack exactly once in seeded random order.

The frozen metrics are full loopback request/response latency for valid and invalid JSON, fresh-child dynamic-import-to-listening readiness, ready-process RSS, and ready-process maximum RSS. Timers include complete response consumption. Reports retain raw observations and R-7 median, quartiles, p95, range, failures, environment identity, exact dependency versions, Git state, lockfile hash, and comparison-source hash.

This comparison is always exploratory and cannot support or reject the primary agent-maintenance hypothesis. NestJS contains Express; loopback, JSON, JIT, GC, thermal state, and background load are confounders; an echo route does not represent a commerce application. A valid maintenance comparison would require independent equivalent applications, a new three-arm corpus and schedule, and 150 fresh provider sessions at five repetitions per task.

Rejected: mutate the frozen two-arm report schema, mix these samples into the primary result, label NestJS as independent of Express, or report unavailable agent-token measurements as estimates.

D-029: Bind the frozen v1 corpus to immutable Git blobs

  • Date: 2026-07-23
  • Status: accepted after publication, before confirmatory observations

The v1 base inventory now identifies commit 5fd027e0399440179859094490b2fa6110f1b30e. Corpus validation and fixture materialization read and SHA-256-check source bytes from that commit rather than from the mutable working tree. All 141 entry hashes remain unchanged. CI checks out full history so the pinned objects are available.

This makes historical evidence reproducible while allowing the live product to evolve. The refresh command is pinned to the same commit and cannot silently replace v1 source hashes with current files.

Rejected: keep live product files frozen indefinitely, refresh v1 entry hashes after every framework change, or weaken digest verification.

D-030: Make operation inspection the bounded agent context surface

  • Date: 2026-07-23
  • Status: accepted after first real-agent UX audit

agentix inspect <operation> --json now emits a typed operation-context projection instead of asking consumers to read the roughly 40 KB internal index. It retains operation/affected/verification data and adds compiler version, source digest, project and target Agentix diagnostics, completeness, and the explicit statement typecheck: "not-run". The artifact has a hard 8 KiB limit: omitted collections expose total/included counts and exact expansion metadata, while a widened affected set reports totals and kind counts instead of every workspace node. Exact IDs, paths, and runnable commands are never shortened; verification widens rather than emitting a partial command. Each omission points either to full affected output or to explicit inspect <operation> --full, an unbounded per-operation detail artifact; normal agent entry remains the bounded form.

The CLI reanalyzes TypeScript for every answer and writes the generated index only as a disposable discovery artifact. It does not trust a structurally valid, same-digest cache to describe source. Programmatic index freshness checks still cover schema/compiler compatibility and source digest.

The default feature scaffold was reduced from six files to three, removing empty model, operation, and invariant modules. A root AGENTS.md and pull-request CI make the context-first path and verification contract discoverable.

Rejected: claim static scanner diagnostics are a TypeScript typecheck, expose the complete index as normal agent context, or generate semantically empty adapter implementations before adapter bindings are indexed.

D-031: Prefer truthful runtime boundaries over the D-017 hot-path shortcut

  • Date: 2026-07-23
  • Status: accepted; supersedes D-017 for current product behavior

Every runtime mode now validates effect success/error payloads. Dispatch latches the first effect/event boundary fault so operation code cannot catch it and return success, closes effect/event capabilities as soon as execute settles, drains every effect started before that point, and rejects a descriptor object that merely reuses a registered stable ID. HTTP handler construction likewise requires exact registered descriptor identity.

Thrown operation-input schema execution is a distinct INPUT_VALIDATION_FAILED fault rather than an invalid-data rejection. Thrown effect-input/event-payload validation, event snapshotting, and hostile adapter outcome inspection are caught and latched under their existing boundary fault families before application code can recover them.

Completed dispatches expose immutable validated emitted events independently of optional traces. Payload graphs made of arrays and plain objects are detached and deeply frozen at emission, with cycles and shared references preserved; non-plain values returned by custom schemas remain opaque. This is dispatch data only; it does not imply publication, delivery, persistence, outbox behavior, or atomicity. The commerce example now uses one explicit finally compensation path to release reserved local stock on all pre-commit failures. Real external payment compensation remains an explicit application design requirement.

The earlier runtime measurements describe the D-017 implementation and are not silently relabeled as measurements of this implementation. A new runtime smoke is required before making current performance statements.

Rejected: preserve production-only schema trust for benchmark continuity, allow caught boundary faults to complete, treat fire-and-forget effects as finished, or describe trace-only event recording as event emission.

D-032: Drive the next context fixes from a fresh-agent pilot

  • Date: 2026-07-23
  • Status: accepted after first bounded-context pilot

A fresh agent started from AGENTS.md and the default orders.create inspect artifact, without reading .agentix/index.json. The artifact was 4,976 bytes against its 8,192-byte limit (the disposable index was 39,374 bytes), required no expansion, and was sufficient to locate the operation, external payment boundary, compensation region, and safe workspace verification. This is a UX observation, not confirmatory benchmark evidence.

The pilot exposed that source-level test metadata linked an invariant-only test but omitted acceptance, concurrency, and architecture coverage that actually protects the operation. Those suites now declare explicit operation-test associations, and the misleading association was removed. The pilot also found that help returned an error and an effect ID could not be inspected; help now exits successfully with complete root syntax, and port operations are directly inspectable by ID.

The remaining observed gap is deliberate and visible: the static projection does not yet index adapter implementation locations or explain ordinary TypeScript execution order/compensation semantics. Agents still follow the operation source and targeted searches for those details. That gap, rather than more research scaffolding, is the next compiler/agent-UX candidate.

D-033: Keep readable JSON and add compact agent transport

  • Date: 2026-07-24
  • Status: accepted after three-arm sandbox token measurement

The notes sandbox showed that Agentix’s recommended context pack paid more declaration overhead than the plain TypeScript and NestJS arms even though its affected closure was much smaller. On the current reference operation, JSON indentation alone accounted for 1,781 of 6,047 output bytes. The CLI therefore accepts --compact with --json on every structured command and the agent entry uses it by default. Compact output preserves the parsed artifact, stable key ordering, and trailing newline; it changes only insignificant whitespace.

Indented --json remains the default for people and existing integrations. The bounded operation projection is still checked against its indented 8 KiB form, so compact transport cannot silently admit data that the documented human-readable artifact would have omitted.

Rejected: make all JSON unreadable by default, remove affected reasons or operation metadata solely to win the token heuristic, or weaken projection completeness and omission reporting.

D-034: Publish coordinated pre-1.0 packages through release pull requests

  • Date: 2026-07-24
  • Status: accepted before the first npm publication

Agentix uses the MIT license and publishes @agentix/core, @agentix/compiler, @agentix/cli, @agentix/testing, and @agentix/adapters-http as public ESM packages requiring Node.js 24. All five packages are one Changesets fixed group: a release pull request owns version, internal dependency-range, changelog, and lockfile updates, and all packages share the same pre-1.0 version. Until 1.0, semantic versioning applies but minor releases may contain breaking API changes.

Every main-branch release run performs the full build, typecheck, test, and frozen-corpus gate before creating the release pull request or publishing. Publication uses npm provenance and is designed to move from one bootstrap NPM_TOKEN to GitHub OIDC trusted publishing. Only framework dist artifacts and package documentation are packed; examples, sandboxes, benchmark code and evidence, and the repository root remain private.

The unscoped agentix name was rejected because it already identifies an unrelated npm package. Independent package versions, publish-on-every-main-push, manual version edits, direct local publication, and mutable version overwrites were rejected because they weaken dependency coherence, reviewability, or recovery.

D-035: Use GitHub prerelease tarballs for the anonymous test channel

  • Date: 2026-07-24
  • Status: accepted before the first GitHub test publication

GitHub test builds attach all five canonical @agentix/* package tarballs to an immutable prerelease. Internal dependencies point to assets in the same release, so applications install directly from public HTTPS URLs without changing import names. Every test release is bound to a Git revision, uses a unique semantic prerelease version, and passes the normal build, package-content, test, and frozen-corpus gates.

GitHub Packages was rejected for the easy-install test channel because its npm registry requires authentication even for public packages and its namespace is the hosting GitHub account. Mutable branch tarballs and uncommitted local uploads were rejected because they do not bind the installed bytes to immutable source.

The package payload deliberately omits source files, tests, build caches, and JavaScript/declaration source maps. Runtime JavaScript and TypeScript declarations remain, together with the package manifest, short package README, and MIT license. CI enforces both forbidden-file rules and per-package file-count budgets so the install cannot silently grow back into a repository snapshot.