diff --git a/project/TICKETS.md b/project/TICKETS.md index f0f11d1..72e672a 100644 --- a/project/TICKETS.md +++ b/project/TICKETS.md @@ -57,4 +57,10 @@ of `project/README.md`, which remains a generated technical-analysis artifact. | **ticket-074** | [`README.md`](./ticket-074/README.md) | [`preprompt.md`](./ticket-074/preprompt.md) | - | [`ai-codex.md`](./ticket-074/ai-codex.md) | [`ai-codex-logs.txt`](./ticket-074/ai-codex-logs.txt) | [`changelog.md`](./ticket-074/changelog.md) | | **ticket-075** | [`README.md`](./ticket-075/README.md) | [`preprompt.md`](./ticket-075/preprompt.md) | - | [`ai-codex.md`](./ticket-075/ai-codex.md) | [`ai-codex-logs.txt`](./ticket-075/ai-codex-logs.txt) | [`changelog.md`](./ticket-075/changelog.md) | | **ticket-076** | [`README.md`](./ticket-076/README.md) | [`preprompt.md`](./ticket-076/preprompt.md) | - | [`ai-codex.md`](./ticket-076/ai-codex.md) | [`ai-codex-logs.txt`](./ticket-076/ai-codex-logs.txt) | [`changelog.md`](./ticket-076/changelog.md) | +| **ticket-077** | [`README.md`](./ticket-077/README.md) | [`preprompt.md`](./ticket-077/preprompt.md) | - | [`ai-devin.md`](./ticket-077/ai-devin.md) | [`ai-devin-logs.txt`](./ticket-077/ai-devin-logs.txt) | [`changelog.md`](./ticket-077/changelog.md) | +| **ticket-078** | [`README.md`](./ticket-078/README.md) | [`preprompt.md`](./ticket-078/preprompt.md) | - | [`ai-gpt-5.6-sol.md`](./ticket-078/ai-gpt-5.6-sol.md) | [`ai-gpt-5.6-sol-logs.txt`](./ticket-078/ai-gpt-5.6-sol-logs.txt) | [`changelog.md`](./ticket-078/changelog.md) | +| **ticket-079** | [`README.md`](./ticket-079/README.md) | [`preprompt.md`](./ticket-079/preprompt.md) | - | [`ai-gpt-5.6-sol.md`](./ticket-079/ai-gpt-5.6-sol.md) | [`ai-gpt-5.6-sol-logs.txt`](./ticket-079/ai-gpt-5.6-sol-logs.txt) | [`changelog.md`](./ticket-079/changelog.md) | +| **ticket-080** | [`README.md`](./ticket-080/README.md) | [`preprompt.md`](./ticket-080/preprompt.md) | - | [`ai-gpt-5.6-sol.md`](./ticket-080/ai-gpt-5.6-sol.md) | [`ai-gpt-5.6-sol-logs.txt`](./ticket-080/ai-gpt-5.6-sol-logs.txt) | [`changelog.md`](./ticket-080/changelog.md) | +| **ticket-081** | [`README.md`](./ticket-081/README.md) | [`preprompt.md`](./ticket-081/preprompt.md) | - | [`ai-gpt-5.6-sol.md`](./ticket-081/ai-gpt-5.6-sol.md) | [`ai-gpt-5.6-sol-logs.txt`](./ticket-081/ai-gpt-5.6-sol-logs.txt) | [`changelog.md`](./ticket-081/changelog.md) | +| **ticket-082** | [`README.md`](./ticket-082/README.md) | [`preprompt.md`](./ticket-082/preprompt.md) | - | [`ai-gpt-5.6-sol.md`](./ticket-082/ai-gpt-5.6-sol.md) | [`ai-gpt-5.6-sol-logs.txt`](./ticket-082/ai-gpt-5.6-sol-logs.txt) | [`changelog.md`](./ticket-082/changelog.md) | diff --git a/project/ticket-078/README.md b/project/ticket-078/README.md new file mode 100644 index 0000000..2f4d3c5 --- /dev/null +++ b/project/ticket-078/README.md @@ -0,0 +1,34 @@ +# Ticket 078: Make governed ticket README NL extraction section-aware + +- **ID**: ticket-078 +- **Owner**: unresolved:human +- **Status**: DONE +- **Workflow state**: DONE +- **Created**: 2026-08-17 + +## Goal and scope + +Make deterministic NL extraction of governed ticket README files safe for +human ticket review. Parse by semantic sections rather than treating +`Status`, `Owner` and wrapped lines as independent requirements. + +Follow-up tickets own missing-path create policy (`src/synthesis`) and +runtime version identity (`src/core/version.ts`). + +## Acceptance criteria + +- [x] AC-01: Governed ticket metadata is excluded from NL intent and wrapped + goals/acceptance criteria remain single records with correct source lines. +- [x] AC-02: Acceptance criteria are classified as validation intent and are not + flagged for missing action/evidence solely because they use `AC-NN`. +- [x] AC-03: Typecheck, tests and governance pass for the extractors scope. + +## Participants + +- Human participant: unresolved; no user-* file was created by this script. +- Agent participant: [ai-gpt-5.6-sol.md](ai-gpt-5.6-sol.md) + +## SESSION_EXECUTION_AUTHORIZATION + +The user's instruction to repair and test the audited tools authorizes this +bounded ticket-safety correction in the extractors workstream. diff --git a/project/ticket-078/ai-gpt-5.6-sol-logs.txt b/project/ticket-078/ai-gpt-5.6-sol-logs.txt new file mode 100644 index 0000000..cc6954e --- /dev/null +++ b/project/ticket-078/ai-gpt-5.6-sol-logs.txt @@ -0,0 +1,445 @@ + +> todo2code@0.5.1 test +> node --test --test-concurrency=4 dist/test/*.test.js + +[t2c:a2a] listening on 127.0.0.1:39261 +[t2c:a2a] listening on 127.0.0.1:33097 +✔ A2A governed-intake skill completes accepted commands and rejects domain failures (153.990915ms) +[t2c:a2a] listening on 127.0.0.1:44739 +✔ A2A v1.0 card, versioning, task methods and cursor pagination are coherent (132.428109ms) +[t2c:a2a] listening on 127.0.0.1:41665 +✔ A2A bearer authentication is declared with v1 security objects and enforced (28.333474ms) +[t2c:a2a] listening on 127.0.0.1:41699 +[t2c:a2a] listening on 127.0.0.1:43057 +[t2c:a2a] listening on 127.0.0.1:46679 +✔ A2A file task store survives restart and preserves idempotency across replicas (122.135748ms) +✔ the A2A bind default is loopback and a wildcard bind is not mistaken for it (2.465921ms) +✔ Go adapter records package, imports, types, functions and methods (131.584387ms) +✔ Go facts are deterministic observations, not inferences (137.560442ms) +✔ Go adapter marks exported symbols and reports calls in scope (201.429992ms) +✔ Go extraction is skipped without cost when a tree holds no Go sources (55.536307ms) +✔ A missing Go toolchain degrades to a warning instead of failing the run (73.35236ms) +✔ Rust adapter records uses, types, functions, methods, values and calls (83.269129ms) +﹣ Java adapter records packages, imports, types, fields, methods and calls (5.425749ms) # JDK not installed +✔ Java and Rust adapters skip toolchain startup when no matching sources exist (20.006607ms) +✔ Missing Java and Rust toolchains degrade to explicit warnings (16.802894ms) +✔ PHP syntax adapter records namespaces, imports, types, functions, methods and calls (145.310134ms) +✔ PHP adapter skips runtime startup when no PHP source exists (19.607379ms) +✔ Missing PHP runtime degrades to an explicit warning (16.827954ms) +✔ Invalid PHP syntax is reported without aborting extraction (80.263801ms) +✔ AST extractor reads TypeScript and Python facts (341.65857ms) +✔ CLI command help is successful and non-mutating (1709.395978ms) +✔ TypeScript and Python CLIs execute the same intake command/query handler (1527.390368ms) +✔ CLI summarize exposes deterministic, prefer-llm and require-llm modes (2769.023779ms) +✔ CLI propose-todo, render-todo and apply-todo return JSON and preserve a no-op TODO (2161.744239ms) +✔ CLI watch reads TASK.md by default, disables summary LLM and reacts to a live file change (2035.950414ms) +✔ proposeCodeChangePlans materialises grounded plans from PLANNED_NOT_IMPLEMENTED (24.68815ms) +✔ code-change title preserves the leading action of a compound intent (3.654301ms) +✔ proposeCodeChangePlans is deterministic for the same evidence (3.848375ms) +✔ a plan creates a missing file and modifies an existing one (12.917176ms) +✔ a plan never invents a repository-root file from a bare filename (2.38161ms) +✔ a plan whose every path is bare and missing is withheld entirely (1.691944ms) +✔ a plan never targets a location outside the repository tree (0.229165ms) +✔ the repository probe never proposes creating a file outside the root (1.367273ms) +✔ bounded plan sets prefer explicit TODO work over historical changelog audit (2.661267ms) +✔ evaluateCodeChangeAcceptance passes when targeted diagnostics clear (6.523824ms) +✔ evaluateCodeChangeAcceptance fails while the plan is still open (2.807758ms) +✔ Plans without repository paths are not invented (0.871996ms) +✔ Non-repository paths are ignored instead of aborting code-change planning (1.27755ms) +✔ Acceptance rejects ungrounded paths, missing provenance and inconsistent verdicts (5.705357ms) +✔ createCodeChangeSourcePatch is deterministic and path-bound (6.688731ms) +✔ applyUnifiedDiffToText creates and modifies files from hunks (1.714199ms) +✔ applyCodeChangeSourcePatch requires approval and is idempotent (24.589375ms) +✔ applyCodeChangeSourcePatch preflights diffs and refuses symlink escapes (11.90669ms) +✔ createCodeChangeSourcePatchSet covers every plan (2.413881ms) +✔ createCodeChangeReviewPatch is hash-stable and lists grounded paths (3.553661ms) +✔ CLI proposes and evaluates a grounded code-change plan through persisted JSON (2536.785512ms) +✔ isUsefulCodeChangePath rejects vendored, binary and analysis dump paths (0.502041ms) +✔ proposeCodeChangePlans skips diagnostics that only name junk paths (2.901694ms) +✔ Published code-change JSON schemas require provenance, risk and rollback (2.556663ms) +✔ participant registry maps stable IDs to Git/A2A identifiers without display-name guessing (51.792968ms) +✔ participant registry rejects ambiguous external identifiers (0.878856ms) +✔ trusted intake persists roles across tickets and fails closed without rejected writes (109.202378ms) +✔ agents cannot create human projections and a damaged event hash fails verification (10.98128ms) +✔ TypeScript and dependency-free Python codecs share golden bytes and preserve unknown fields (427.201627ms) +✔ communication enrichment preserves runtime identity, source, ticket and epistemic class (133.632687ms) +✔ communication enrichment corrects one rejected structured response without weakening validation (25.991318ms) +✔ communication prefer-llm fallback is explicit and require-llm rejects (35.416604ms) +✔ project/ communication is attributed per human and agent and checked against Git evidence (327.171429ms) +✔ governance user-* and ai-* files become typed participant intent without ingesting ticket evidence (20.3149ms) +✔ unstructured governance participant content is rejected with an owner-specific migration warning (2.972629ms) +✔ opposite wording about different explicit files is not treated as an intent conflict (21.334532ms) +✔ missing response owners use explicit role sentinels without inventing participants (17.784837ms) +✔ communication extractor reports unresolved identity instead of inventing an actor (4.223906ms) +✔ communication extractor ignores generic generated analysis under project/ (17.900424ms) +✔ explicit OPENROUTER_APP_NAME overrides the project folder name (1.866495ms) +✔ missing or blank OPENROUTER_APP_NAME falls back to the resolved project folder (1.015579ms) +✔ OpenRouter application identity remains non-empty for a filesystem root (0.450715ms) +✔ configuration converter covers JSON, TOML, Docker and CI workflow declarations (34.883549ms) +✔ configuration converter emits a deterministic file aggregate for an empty configuration (7.116891ms) +✔ splitLines treats a trailing newline as a terminator, not an extra line (2.70009ms) +✔ Identical inputs produce no hunks (0.851098ms) +✔ A modified line keeps both sides addressable by original line number (0.76777ms) +✔ Pure insertion and pure deletion are not reported as replacements (0.435656ms) +✔ Empty-to-content and content-to-empty are handled as block changes (0.509303ms) +✔ Context width controls hunk size (0.321947ms) +✔ Nearby changes merge into a single hunk (0.298236ms) +✔ Distant changes stay in separate hunks (0.274432ms) +✔ Oversized inputs fall back to a bounded block replace (0.803522ms) +✔ Unified output carries a well formed hunk header (0.728485ms) +✔ Side-by-side rows pair deletions with insertions (0.426809ms) +✔ Unbalanced change runs leave one side empty rather than misaligning (0.257267ms) +✔ Renderers escape source markup (1.602623ms) +✔ SVG rendering caps rows and reports the remainder (2.01443ms) +✔ Reality view keys topics by target and records lane presence (22.27506ms) +✔ A topic holding declared and observed records is never reported as planned-only (3.130162ms) +✔ Reality coverage stays open when a shared path has unrelated capabilities (2.287006ms) +✔ Shared-path relations do not collapse unrelated files into one topic (2.624625ms) +✔ Reality view is deterministic for identical input (3.803767ms) +✔ Reality SVG escapes topic labels (7.586721ms) +✔ graph diff detects changed source identities, additions and SVG-safe labels (23.71545ms) +✔ graph diff is empty for graphs with identical evidence (3.488475ms) +✔ file diff emits deterministic unified, SVG and HTML views (3.899299ms) +✔ intent-vs-reality builds an explainable SVG and Markdown projection (5.917232ms) +✔ a targetless declaration is filed under the single module it links to (7.704594ms) +✔ a declaration touching several modules keeps its own topic (4.915538ms) +✔ a topic about a document does not absorb the statements written in it (21.340175ms) +✔ semantically aligned configuration topics retain their evidence grade (2.896491ms) +✔ A record claiming line 1 is re-anchored to the line carrying its statement (75.287306ms) +✔ An already correct line is kept and not reported as re-anchored (7.461854ms) +✔ An empty target is backfilled from the statement text (13.345208ms) +✔ A target supplied by the model is never overwritten (18.574591ms) +✔ An unclassified action and modality are derived from the statement (10.346112ms) +✔ A classified action from the model wins over the heuristic (13.531382ms) +✔ An action that stays unclassifiable is reported as a missing field (12.721513ms) +✔ A placeholder object is treated as a gap, not as content (5.627526ms) +✔ Every repair is attributable through epistemic.basis (7.709364ms) +✔ standalone source DSL facades preserve their canonical extractor results (89.986011ms) +✔ standalone source DSL facades reject invalid or foreign roots and files (1.892664ms) +✔ governed ticket README keeps wrapped goals and drops lifecycle metadata (17.551774ms) +✔ generic TASK.md line segmentation stays unchanged for headings (1.269203ms) +✔ deterministic documentation baseline records headings, code blocks and explicit references (21.836243ms) +✔ deterministic documentation preserves Polish prohibition polarity (9.598653ms) +✔ deterministic documentation resolves a unique bare filename against the repository (15.281129ms) +✔ documentation prose resolves a bare filename to its repository location (6.784454ms) +✔ a nested checkout does not shadow the repository copy of a documented file (7.29721ms) +✔ AST cache is incremental by path and source content hash (41.211398ms) +✔ AST cache rejects corrupt entries and recomputes authoritative records (12.941675ms) +✔ AST cache can be bypassed without changing extraction output (6.5162ms) +✔ successful external AST adapter is skipped on a warm manifest hit (320.365506ms) +✔ documentation chunks cache independently while provider calls remain live (36.428155ms) +✔ generated analysis replaces its source root with a stable token (80.637899ms) +✔ generated analysis root normalization refuses the filesystem root (47.160346ms) +✔ generated analysis rejects references to untracked input (105.707935ms) +✔ generated analysis accepts outputs independent of untracked input (89.388281ms) +✔ generated analysis accepts an untracked filename already quoted by tracked evidence (94.084506ms) +✔ generated analysis rejects temporary paths and unavailable validators (96.883464ms) +✔ generated README metadata is synchronized from package.json and stays idempotent (91.723323ms) +✔ generated README synchronization fails closed when the template drifts (49.134029ms) +✔ generated README synchronization rejects output outside the project root (46.742506ms) +✔ generated task and TODO projections are evidence unless communication explicitly opts in (41.672895ms) +✔ malformed front matter is rejected and non-ISO timestamps are reported (7.606057ms) +✔ assembles cited added, removed and modified truth changes (29.639942ms) +✔ keeps textual and semantic conflicts separate and cited (12.00792ms) +✔ unanchored cross-branch additions fail closed as unknown manual review (7.411855ms) +✔ duplicate changed source identities fail closed as unknown (17.069654ms) +✔ reuses one semantic bundle for refs sharing an exact tree (10.194746ms) +✔ rejects tampered Git materialization and mismatched semantic artifacts (3.070547ms) +✔ semantic bundle order and generated time do not alter portfolio identity (7.134702ms) +✔ materializes exact topology, conflicts, disjoint paths and equivalent patches read-only (611.942741ms) +✔ fingerprint is invariant to ref order and contains no clock metadata (600.4065ms) +✔ merge-tree result classifier fails closed on unavailable or ambiguous output (0.358968ms) +✔ rejects unsafe, duplicate, symbolic, missing and over-limit refs (215.88182ms) +✔ detects ref movement and removes temporary state after failure (272.475518ms) +✔ clean expected branch produces an exact deterministic PASS without changing Git state (576.476387ms) +✔ tracked, untracked and renamed paths are sorted and block a dirty workspace (378.396684ms) +✔ porcelain-v2 conflict facts and path bounds fail closed deterministically (17.686921ms) +✔ behind, detached and unexpected branches expose stable diagnostics and safe actions (819.346452ms) +✔ an ahead-only isolated branch remains usable but records a sync warning (317.282669ms) +✔ managed governance findings remain authoritative and unresolved scope blocks (305.306314ms) +✔ governance process failures keep their domain code and redact stderr (282.139616ms) +✔ implementation paths receive only the ticket selected by managed governance (300.812871ms) +✔ invalid roots, refs, checker output and options fail closed with stable codes (678.898519ms) +✔ report has no command, credential or absolute-root output and failure is read-only (568.871327ms) +✔ Git extractor emits one record per requested commit (300.561631ms) +✔ An empty repository degrades to a warning instead of failing the run (13.317023ms) +✔ versioned gold dataset reports perfect offline quality and repeated-run stability (206.299403ms) +✔ gold linking reports exact-target and capability-topic quality separately (96.078612ms) +✔ gold capability-topic support is large enough to detect a floor regression (82.256673ms) +✔ gold known gaps are measured and kept out of precision and recall (92.219964ms) +✔ gold reports cross-language positives and hard negatives as a separate cohort (79.432986ms) +✔ gold diagnostics separate a false DONE claim from an evidenced one (129.938165ms) +✔ gold v1 stays evaluable after the v2 contract extension (35.343682ms) +✔ gold loader rejects unsupported dataset versions (0.77933ms) +✔ gold evaluator rejects unknown linking cohorts (2.000048ms) +✔ gold v2 must declare diagnostics coverage (1.23573ms) +✔ published gold schema matches the runtime contract (1.803211ms) +✔ gold evaluator rejects fixture files outside its temporary workspace (8.900594ms) +✔ disjoint immutable candidates are bound to exact snapshots and merge-ready (17.597904ms) +✔ equivalent patch identity detects duplicate work across different commits (1.512507ms) +✔ textual and semantic conflicts stay separate and both block candidates (1.713339ms) +✔ contained or proven empty work is stale while unknown evidence requires review (0.892347ms) +✔ ordering and target movement produce merge-after and rebase recommendations (1.167937ms) +✔ ordering and generated time do not affect identity but a changed base does (3.262547ms) +✔ malformed identities and ungrounded semantic conflicts fail closed (0.913593ms) +✔ repository, counts, enums, digests and timestamps are validated strictly (0.605596ms) +✔ incomplete pair semantics cannot be classified as disjoint (0.883028ms) +✔ base semantic evidence and ordering citations survive projection (1.021629ms) +✔ ordering without related relation evidence fails closed (0.374385ms) +✔ missing, duplicate and self candidate pairs fail closed (0.554194ms) +✔ no unique work remains stale even when another branch has the same tree (0.678963ms) +✔ portfolio validation rejects tampering and authorization-like fields (1.147235ms) +✔ truth map groups explicit semantic evidence and preserves complete lineage (19.075651ms) +✔ structural relations do not collapse independent assertions (2.83946ms) +✔ explicit contradiction is visible and never selects a winner (1.645104ms) +✔ mixed claims remain distinct from factual support (1.321852ms) +✔ IDs and fingerprints are invariant to graph ordering and generatedAt (1.978943ms) +✔ invalid graph fingerprint and dangling relation endpoints fail closed (1.038099ms) +✔ truth map validator rejects duplicate assertion membership and reverse drift (1.382436ms) +✔ truth map validator rejects omitted mapping relations and artificial grouping (3.172358ms) +✔ Linker connects plan, Git claim and AST fact (19.054291ms) +✔ Linker connects prose intent to a module through three grounded capability topics (1.591195ms) +✔ Linker does not connect a module on one generic topic alone (1.211951ms) +✔ An existing target path does not prove an unrelated capability (2.387256ms) +✔ An existing target path plus an AST capability proves implementation (1.886369ms) +✔ Diagnostics distinguish descriptive documentation from prescriptive requirements (3.573631ms) +✔ A changelog entry naming an extracted documentation file has release evidence (1.949839ms) +✔ Diagnostics ignore non-actionable changelog mechanics but retain release claims (6.397575ms) +✔ Grounded conclusion and TODO proposal contracts accept traceable values (10.871935ms) +✔ Stable IDs ignore ordering noise but change with semantic content (1.106974ms) +✔ Validators reject ungrounded citations and stale semantic IDs (3.297196ms) +✔ Generation metadata exposes LLM failures instead of silently masking them (2.003469ms) +✔ TODO proposal collections enforce dependency integrity (1.239192ms) +✔ Published JSON schemas identify all grounded output contract versions (18.221869ms) +✔ Blank lines and comments produce no rules (2.099387ms) +✔ A pattern without a slash matches at any depth (0.736535ms) +✔ A leading slash anchors the pattern to the root (0.318951ms) +✔ A trailing slash restricts the rule to directories (0.331521ms) +✔ Wildcards respect path separators (0.659509ms) +✔ Every dot-directory is excluded by `.*/` (0.417372ms) +✔ Negation re-includes a previously excluded path (0.453436ms) +✔ Negation cannot resurrect a file inside an excluded directory (0.295158ms) +✔ Last matching rule wins (0.412171ms) +✔ Character classes are supported (0.501667ms) +✔ Paths are normalised before matching (0.302711ms) +✔ loadIgnoreMatcher merges the three ignore files and skips missing ones (27.078406ms) +✔ A repository without ignore files excludes nothing (2.200405ms) +✔ The shipped .intentignore excludes build output but keeps sources (3.170667ms) +✔ resolveGlobs permits one explicit .intent report without recursively scanning generated runs (11.457033ms) +✔ Two unrelated AST facts sharing only a file are not linked (18.895813ms) +✔ AST facts sharing a symbol are still linked despite the path rule (2.206917ms) +✔ AST details sharing only a file and generic tokens do not create a quadratic subgraph (4.685502ms) +✔ A file-level plan links once to the AST module aggregate instead of every detail (6.709808ms) +✔ A shared path still links a plan to an AST fact (1.218453ms) +✔ A bare filename links to a module only when its repository path is unique (1.884882ms) +✔ A bare filename refuses ambiguous module paths (0.913013ms) +✔ Relations that carry a conclusion survive alongside suppressed noise (2.190827ms) +✔ Pair ordering stays deterministic across rebuilds (2.270339ms) +✔ Two configuration declarations sharing only a key name are not linked (0.717297ms) +✔ A shared ticket still connects two configuration declarations (0.520709ms) +✔ Configuration still links to documentation that describes it (0.42794ms) +✔ Configuration file aggregate is the file-level target for an explicit documentation path (0.689817ms) +✔ Configuration aggregates do not create broad capability-topic links (0.561252ms) +✔ a full six-stage live run passes and reports every stage (3.947563ms) +✔ a stage that silently fell back to deterministic fails the check (0.739741ms) +✔ a missing stage cannot pass as covered (0.3652ms) +✔ per-stage and total budgets are enforced separately (0.476309ms) +✔ live request timeout reaches the stage budget without shortening a larger override (0.252644ms) +✔ a stage reason is recorded with provider text redacted (0.924445ms) +✔ history records the trend without gating on it (0.60752ms) +✔ recorded audit history includes the current run exactly once (0.846144ms) +✔ history stays chronological, bounded and free of duplicate runs (11.346993ms) +✔ an audit converts to exactly the redacted fields history keeps (0.453322ms) +✔ an empty history summarizes without pretending to have measured anything (0.152953ms) +✔ a batched run is measured per record, not per request (6.027503ms) +✔ a model whose response the validator rejected is not counted as enriched (0.360593ms) +✔ a failed model is a comparison result rather than a crash (1.188529ms) +✔ agreement compares only records both models enriched (0.520692ms) +✔ agreement is absent rather than perfect when nothing overlaps (0.764733ms) +✔ the rendered comparison names the cheapest and fastest passing model (0.429459ms) +✔ semantic LLM modes default to require-llm (1.407145ms) +✔ Markdown extractor separates TODO plans and changelog claims (20.5503ms) +✔ Markdown extractor preserves indented continuation lines and their source range (6.348927ms) +✔ TODO bare filenames inherit an existing directory from the heading scope (2.247162ms) +✔ TODO resolves a bare filename only when its repository basename is unique (2.86714ms) +✔ TODO and CHANGELOG resolve the same bare filename to one repository path (3.653225ms) +✔ CHANGELOG keeps an ambiguous bare filename unresolved (2.53657ms) +✔ Markdown path resolution drops paths and heading scopes outside the repository (1.712009ms) +✔ TODO and CHANGELOG receive audited LLM enrichment without changing structural facts (34.235929ms) +✔ Markdown enrichment corrects one rejected response and audits both attempts (5.898499ms) +✔ large Markdown enrichment uses bounded concurrency and keeps provider audits ordered (56.936022ms) +✔ TODO and CHANGELOG LLM fallback and require mode are explicit (5.307019ms) +✔ TODO and CHANGELOG reject structurally invalid LLM enrichments (5.674785ms) +✔ a truncated batch is split and every record keeps its own response provenance (8.432046ms) +✔ a malformed batch response splits instead of failing the whole stage (8.775477ms) +✔ MCP 2026 profile is stateless and exposes discovery plus complete results (6.993922ms) +✔ MCP 2026 rejects missing metadata and unsupported versions with protocol errors (1.199315ms) +✔ MCP legacy profile negotiates 2025-11-25 and requires initialize (0.641126ms) +✔ MCP exposes annotated intake command/query tools backed by the domain handler (24.674715ms) +✔ An LLM record is marked as inference and keeps runtime-owned provenance (45.849304ms) +✔ NL extraction corrects one rejected structured response and audits both attempts (6.132146ms) +✔ Confidence must satisfy the provider schema instead of being silently clamped (14.236885ms) +✔ Source lines are clamped to the real file (2.864402ms) +✔ A placeholder object is recorded as a missing field, not as content (14.201696ms) +✔ A real object is kept verbatim and reports no missing field (2.27247ms) +✔ The explicit unknown action is reported as a missing field (6.108921ms) +✔ Both gaps are reported together (5.868222ms) +✔ Out-of-vocabulary enums are rejected instead of changing the provider intent (4.262539ms) +✔ Rejected NL output keeps provider metadata in the failed audit (2.879402ms) +✔ The documented confidence hierarchy holds across LLM extractors (1.07646ms) +✔ NL extractor produces deterministic non-LLM records (9.344054ms) +✔ NL public extraction boundary names a missing sourcePath before path resolution (1.070999ms) +✔ deterministic NL fallback skips Markdown headings and recognizes comparison intent (2.916771ms) +✔ path extraction rejects lowercase prose alternations without losing repository paths (1.859955ms) +✔ path extraction rejects dotted DSL fields but keeps known file extensions (0.396453ms) +✔ detectModality ignores parenthetical labels and bare adjectives (0.560448ms) +✔ detectModality reads prohibitions and periphrastic obligation as requirements (0.780628ms) +✔ detectPolarity does not treat without-complements as sentence negation (0.288986ms) +✔ path extraction rejects HTTP routes, host paths and parent traversal (0.287586ms) +✔ symbol extraction rejects hostnames without losing qualified code symbols (0.497051ms) +✔ symbol extraction separates repository files and all-caps prose from code identifiers (0.321749ms) +✔ topic keywords normalize paths, camelCase and documentation word forms (0.518264ms) +✔ NL LLM extraction emits audited provenance and bounded DSL records (48.53757ms) +✔ NL LLM failure is explicit when deterministic fallback is used (5.445745ms) +✔ require-llm rejects instead of silently falling back (0.691607ms) +✔ adaptive OpenRouter timeout scales at exact power-of-two boundaries (1.704732ms) +✔ output budget and structural complexity independently scale timeout (0.381909ms) +✔ adaptive OpenRouter timeout caps at ten minutes (0.240135ms) +✔ adaptive OpenRouter timeout rejects malformed and unbounded inputs (1.869226ms) +✔ OpenRouter audit records the non-secret adaptive timeout policy (1.035272ms) +✔ external cancellation remains immediate before an OpenRouter fetch (0.898871ms) +✔ retry backoff remains inside one effective OpenRouter deadline (27.493649ms) +✔ OpenRouter client parses structured JSON without exposing key (27.253058ms) +✔ OpenRouter client preserves metadata when runtime rejects structured output (2.057353ms) +✔ OpenRouter client lists available models after an invalid model ID (13.87769ms) +✔ OpenRouter client redacts provider key-management evidence while retaining the failure reason (1.321445ms) +✔ OpenRouter model-list failures redact credentials and contextual credential identifiers (1.212119ms) +✔ OpenRouter JSON timeout is not repeated as a schema fallback request (0.81958ms) +✔ OpenRouter request obeys a shared pipeline deadline without retrying (1.037184ms) +✔ Documentation extractor converts OpenRouter structured output to bounded LLM records (18.15295ms) +✔ Documentation extractor reports and enforces its chunk budget (7.252237ms) +✔ Documentation extractor corrects one rejected chunk and audits both responses (6.930497ms) +✔ Documentation extractor does not spend its correction retry on a timeout (4.792721ms) +✔ Documentation extractor exposes an audited configuration failure (0.514016ms) +✔ Documentation extractor uses bounded concurrent OpenRouter requests (36.185606ms) +✔ LLM summarizer receives graph data and preserves grounded record citations (10.389331ms) +✔ LLM summarizer validates provider fields before creating semantic IDs (5.683821ms) +✔ LLM summarizer diagnoses a provider that ignores the response envelope (6.442339ms) +✔ LLM summarizer rejects diagnostic citations outside the supplied graph (6.883677ms) +✔ LLM summarizer prioritizes documentation over the AST payload budget (209.263842ms) +✔ deterministic summary presents AST module aggregates instead of low-level calls (1.554446ms) +✔ The summarizer grounds a fabricated record citation from its diagnostic (5.17848ms) +✔ The summarizer still fails when the retry fabricates a diagnostic again (2.667118ms) +✔ variable contracts and operation plans have deterministic content-bound IDs (5.948153ms) +✔ every variable grants Founder read/write authority and immutable variables reject other writers (0.718458ms) +✔ plans reject undeclared parameters, actor visibility gaps and payload secrets (1.181388ms) +✔ safety-sensitive commands require a Founder decision, a human boundary and verification (1.315267ms) +✔ plan hash detects semantic tampering (1.595715ms) +✔ compiler emits the exact governed envelope without an execution surface (1.124469ms) +✔ runtime draft boundaries ignore lifecycle and identity fields injected by untyped callers (0.588234ms) +✔ compiler fails closed on extra, stale, wrong-source and wrong-type bindings (1.298911ms) +✔ file boundary writes one private envelope atomically and refuses overwrite (12.925758ms) +✔ canonical ticket-045 fixture parses and renders byte-for-byte (25.985008ms) +✔ identical semantic inputs render identically and sort by canonical recording order (1.476217ms) +✔ parser fails closed on tampered chains and non-canonical encoding (1.241092ms) +✔ unsafe evidence, secrets and advisory approval are rejected before rendering (0.725033ms) +✔ writer publishes one validated file atomically and refuses an immutable overwrite (10.93711ms) +✔ Offline pipeline writes a complete run (226.790864ms) +✔ Pipeline writes a canonical event log for a successful deterministic run (57.421644ms) +✔ Pipeline persists synthesis, validation and review patch, then registers approval receipt (52.274188ms) +✔ Pipeline integrates multi-participant communication into graph, diagnostics, reality and run artifacts (60.240122ms) +✔ Pipeline require-llm task synthesis failure is audited and never publishes latest (28.909486ms) +✔ Pipeline persists an audited failure when communication require-llm cannot run (32.143539ms) +✔ Pipeline persists communication stage failure and does not publish latest (30.373255ms) +✔ Pipeline persists a failed manifest when NL require-llm aborts (17.145324ms) +✔ Pipeline persists a failed manifest when Markdown require-llm aborts (40.130231ms) +✔ Pipeline persists a failed manifest for an unexpected summary failure (36.715554ms) +✔ Proposal validation reports existing TODO duplicates and orders dependencies before priority (21.094499ms) +✔ Proposal validation rejects dependency cycles and whitespace-only criterion duplicates (2.12111ms) +✔ Python package executes the local TypeScript reality runtime without a server (2275.820328ms) +✔ runtime cycle extractor turns probes, violations, drift and proposals into records (18.885291ms) +✔ measurements enter as fact and the cycle own suggestions as inference (2.750272ms) +✔ a violated expectation is negative and blocked, a healthy probe positive and verified (2.459596ms) +✔ a probe that could not run is unknown, not failing (1.80368ms) +✔ a watched path lets a runtime fact link to the code that produces it (19.953759ms) +✔ a document that is not an autonom cycle is refused by schema, not silently empty (1.551088ms) +✔ Runtime validator enforces the complete Intent DSL enum and object contract (7.289146ms) +✔ Linker and remote action boundary reject malformed records before graph construction (11.666932ms) +✔ Graph validator rejects invalid relations and inconsistent statistics (4.137968ms) +[t2c:a2a] listening on 127.0.0.1:33141 +✔ diff UI and TypeScript/Python SDKs use the live backend runtime (697.99032ms) +✔ MCP/A2A action boundary rejects traversal and symlink escapes (56.510363ms) +✔ bounded retrieval cannot create a relation until a grounded reranker accepts it (31.936994ms) +✔ reranker fails closed on ungrounded quotes and more than one accepted module (7.216321ms) +✔ OpenRouter reranking is required, structured and reusable only through an identity-bound cache (117.999487ms) +✔ published semantic reranker schemas expose the versioned bounded contracts (1.885351ms) +✔ provider response validation diagnoses the exact property without coercion (0.560306ms) +✔ analysis policy renders and parses one canonical byte representation (3.765742ms) +✔ deterministic triggers select required LLM stages and exact usage ceilings (0.803008ms) +✔ selection rejects unknown, duplicate and non-canonical trigger input (0.86725ms) +✔ policy and exact-evidence cache fingerprints bind every semantic input (4.367677ms) +✔ token ceilings convert to a deterministic provider-rate cost bound (0.44898ms) +✔ policy rejects semantic fallback and non-exact cache modes (0.716865ms) +✔ stage topology and nested budgets fail closed (1.442173ms) +✔ parser rejects non-canonical and structurally ambiguous text (0.759553ms) +✔ one structured contract emits the provider schema and parses the same value (2.826883ms) +✔ structured parsing fails closed with the exact response path (2.668741ms) +✔ object uniqueness uses canonical JSON identity rather than property order (0.4559ms) +✔ SubLLM bridge resolves the selected central route without command-shell interpolation (391.331322ms) +✔ todo2code sends structured semantic requests through direct Z.AI resolved by SubLLM (345.11442ms) +✔ explicitly requested SubLLM fails closed when its package is unavailable (2.703043ms) +✔ a short NL symbol resolves to its only AST owner (22.950705ms) +✔ an ambiguous short NL symbol does not pretend that either AST owner is selected (4.571274ms) +✔ an explicit path selects one owner of an otherwise ambiguous symbol (2.026526ms) +✔ a qualified symbol selects its exact AST declaration without a path (1.401157ms) +✔ a symbol and explicit path conflict reports the observed AST location (1.73074ms) +✔ missingFields diagnostics prescribe a concrete edit for every known gap (0.768771ms) +✔ Target normalization canonicalizes paths, symbols and cross-language separators (2.050204ms) +✔ Qualified AST symbols align with short plan and documentation targets (17.333593ms) +✔ Structured task synthesis materializes stable, grounded contracts with a complete audit (50.371808ms) +✔ blank response-local proposal keys are rejected instead of invented by the runtime (6.402277ms) +✔ prefer-llm exposes raw diagnostic actions without claiming semantic task generation (1.557342ms) +✔ communication divergence is grounded in task synthesis without treating agent claims as facts (7.982836ms) +✔ task synthesis defaults to require-llm and fails explicitly without a provider (1.199214ms) +✔ invalid structured LLM citations are rejected or visibly degraded according to mode (11.443945ms) +✔ task synthesis timeout is audited and never retried as a format fallback (15.222134ms) +✔ A fabricated record citation is grounded from its cited diagnostic without a retry (5.933233ms) +✔ A fabricated diagnostic still fails after the corrective retry (5.420635ms) +✔ TensorFlow remains an explicit fallback when the isolated adapter is not installed (5.723822ms) +✔ TODO patch rendering is stable, dependency-first and excludes classified duplicates (19.42776ms) +✔ empty and duplicate-only results render an explicit no-op patch (2.364599ms) +✔ apply rejects missing or wrong approval, stale TODO and a tampered patch (10.524108ms) +✔ approved apply is atomic, receipt-backed and idempotent (7.541223ms) +✔ service actions execute LLM propose -> render -> approved apply with scoped artifacts (37.242463ms) +✔ scanTree prunes ignored directories and records file signatures (16.50863ms) +✔ diffSnapshots classifies additions, modifications and removals (0.481645ms) +✔ describeDelta truncates long change lists (0.146849ms) +✔ An unchanged tree produces exactly one report and then stays quiet (3.49988ms) +✔ Reports are rate limited to one per interval no matter how often files change (20.290055ms) +✔ A change is reported once the interval has elapsed (8.140427ms) +✔ Ignored files never trigger a report (3.684597ms) +✔ A failing report is surfaced and does not stop the watcher (1.592872ms) +✔ --no-initial-report waits for a real change (1.296214ms) +✔ Communication changes trigger watch and coalesce under the existing report rate limit (3.677747ms) +✔ workflow verifier rejects duplicate top-level YAML keys (105.879067ms) +✔ workspace preflight help and required input fail before repository inspection (122.552704ms) +✔ workspace preflight maps canonical PASS and BLOCKED reports without Git mutation (558.081689ms) +✔ Make quotes caller input as one argument in its preflight recipe (2.860267ms) +✔ Make preflight reserves stdout for one canonical report (6553.815637ms) +✔ GitHub event collector maps supported push payloads to canonical event logs (71.299658ms) +✔ GitHub review events are SYSTEM_FACT and cannot become approval attestation (41.873427ms) +✔ GitHub review with unsupported state fails closed (39.614454ms) +✔ Evidence projection is allowlisted and extra payload fields do not leak into logs (87.120839ms) +✔ GitHub acquisition ignores ambient environment and requires explicit input (136.855849ms) +✔ workspace comparison deadline scales aggregate input and LLM work in bounded 2x steps (1.197417ms) +✔ workspace headline trend ignores AST-only topic and source churn (0.26231ms) +✔ workspace comparison measures origin/main against uncommitted filesystem intent (581.179535ms) +ℹ tests 424 +ℹ suites 0 +ℹ pass 423 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 1 +ℹ todo 0 +ℹ duration_ms 18747.925848 +GOV-PASS: passed (0 errors, 0 warnings) diff --git a/project/ticket-078/ai-gpt-5.6-sol.md b/project/ticket-078/ai-gpt-5.6-sol.md new file mode 100644 index 0000000..46e8bf1 --- /dev/null +++ b/project/ticket-078/ai-gpt-5.6-sol.md @@ -0,0 +1,34 @@ +--- +participant-id: agent:gpt-5.6-sol +participant: gpt-5.6-sol +role: agent +ticket: ticket-078 +--- +# Participant: gpt-5.6-sol (AI agent) + +## Understanding + +Governed ticket README files were split line-by-line, so lifecycle metadata and +wrapped acceptance criteria became false NL requirements. + +## Execution plan + +1. Segment `project/ticket-*/README.md` by Goal / Acceptance sections. +2. Classify AC segments as `validate` and skip metadata fields. +3. Keep generic TASK.md segmentation unchanged. +4. Prove with tests and governance in the extractors workstream. + +## Actual changes + +- `src/extractors/nl.ts`: ticket README section segmentation; AC → `validate`. +- `test/docs-ticket-readme.test.ts`: governed README fixture coverage. +- `test/docs.test.ts`: bind provenance assertion to `T2C_VERSION`. + +## Follow-ups + +- Missing nested-path `create` withholding → synthesis/runtime ticket. +- Runtime provenance `0.5.1` alignment → core-dsl + owned test tickets. + +## Blockers + +- None for the extractors slice. diff --git a/project/ticket-078/changelog.md b/project/ticket-078/changelog.md new file mode 100644 index 0000000..100e415 --- /dev/null +++ b/project/ticket-078/changelog.md @@ -0,0 +1,13 @@ +# Ticket Changelog (ticket-078) + +## [0.2.0] - 2026-08-17 + +- Governed ticket README NL extraction ignores lifecycle metadata and keeps + wrapped goals/acceptance criteria as single records classified as + validation intent. +- Documentation provenance assertions bind to `T2C_VERSION`. + +## [0.1.0] - 2026-08-17 + +- Initial governance scaffold created. +- No human participant identity or content was generated. diff --git a/project/ticket-078/intent.json b/project/ticket-078/intent.json new file mode 100644 index 0000000..947e6d0 --- /dev/null +++ b/project/ticket-078/intent.json @@ -0,0 +1,76 @@ +{ + "schema": "new-project.intent/v3", + "ticket": "ticket-078", + "summary": "Make governed ticket README NL extraction section-aware", + "workstream": "extractors", + "classification": { + "kind": "FEATURE", + "priority": "P1", + "origin": "requested" + }, + "allowedPaths": [ + "project/ticket-078/**", + "TODO.md", + "project/TICKETS.md", + "src/extractors/nl.ts", + "test/docs.test.ts", + "test/docs-ticket-readme.test.ts" + ], + "forbiddenPaths": [ + "project/ticket-*/user-*.md", + "src/synthesis/**", + "src/core/**", + "src/pipeline/**", + "test/nl.test.ts" + ], + "stacks": ["node"], + "dependsOn": [], + "conflictsWith": [], + "integrationTicket": null, + "delivery": { + "acceptedBaseSha": "680944ff22ee2f429d044ec9b40d2150a1b494c5", + "targetBranch": "main", + "outcome": "Deterministic NL extraction of governed ticket README files ignores lifecycle metadata, keeps wrapped goals and acceptance criteria as single records, and classifies AC lines as validation intent.", + "nonGoals": [ + "No code-change plan create-policy changes", + "No runtime version identity bump", + "No changes to generic TASK.md line segmentation" + ], + "complexity": "S", + "estimatedMinutes": 25, + "budgets": { + "maxImplementationFiles": 3, + "maxAffectedComponents": 1, + "maxPublicInterfaceChanges": 0, + "maxRuntimeDependencies": 0 + }, + "architecture": { + "status": "accepted", + "decision": "Apply source-aware ticket README segmentation at the NL extractor boundary for project/ticket-*/README.md only.", + "components": [ + { + "name": "ticket-intent-extraction", + "paths": ["src/extractors/nl.ts", "test/docs-ticket-readme.test.ts", "test/docs.test.ts"] + } + ], + "responsibilityChanges": false, + "interfaceChanges": [], + "dataChanges": [], + "ui": {"impact": "none", "states": [], "evidence": []}, + "rollback": "Restore generic line segmentation for governed ticket README files." + }, + "runtimeDependencies": [], + "validation": [ + { + "criterion": "AC-01", + "commands": ["npm run check", "npm run build", "npm test"], + "evidence": "project/ticket-078/ai-gpt-5.6-sol-logs.txt" + }, + { + "criterion": "AC-03", + "commands": ["./project/governance-check.sh --actor agent"], + "evidence": "project/ticket-078/ai-gpt-5.6-sol-logs.txt" + } + ] + } +} diff --git a/project/ticket-078/preprompt.md b/project/ticket-078/preprompt.md new file mode 100644 index 0000000..3b80d84 --- /dev/null +++ b/project/ticket-078/preprompt.md @@ -0,0 +1,8 @@ +# Ticket preprompt + +- **Task ID**: ticket-078 +- **Task title**: Make deterministic plans ticket-safe +- **Created**: 2026-08-17T10:50:17Z + +Keep executable implementation outside this governance/evidence directory. +Read a human-owned user-*.md file only when one exists. diff --git a/project/ticket-079/README.md b/project/ticket-079/README.md new file mode 100644 index 0000000..590bae2 --- /dev/null +++ b/project/ticket-079/README.md @@ -0,0 +1,31 @@ +# Ticket 079: Withhold invented create plans for missing nested paths + +- **ID**: ticket-079 +- **Owner**: unresolved:human +- **Status**: DONE +- **Workflow state**: DONE +- **Created**: 2026-08-17 + +## Goal and scope + +Deterministic code-change plans must not invent `create` actions for missing +nested repository paths when the source only describes or updates them. +Explicit add/create/implement intents may still propose missing files. + +## Acceptance criteria + +- [x] AC-01: Descriptive update intents keep existing paths as `modify` and + withhold missing nested paths instead of inventing `create`. +- [x] AC-02: Explicit add/create intents may still propose `create` for missing + nested paths. +- [x] AC-03: Typecheck, tests and governance pass for the llm workstream scope. + +## Participants + +- Human participant: unresolved; no user-* file was created by this script. +- Agent participant: [ai-gpt-5.6-sol.md](ai-gpt-5.6-sol.md) + +## SESSION_EXECUTION_AUTHORIZATION + +The user's instruction to continue repairing audited tools authorizes this +bounded create-safety correction after ticket-078. diff --git a/project/ticket-079/ai-gpt-5.6-sol-logs.txt b/project/ticket-079/ai-gpt-5.6-sol-logs.txt new file mode 100644 index 0000000..dafa051 --- /dev/null +++ b/project/ticket-079/ai-gpt-5.6-sol-logs.txt @@ -0,0 +1,446 @@ + +> todo2code@0.5.1 test +> node --test --test-concurrency=4 dist/test/*.test.js + +[t2c:a2a] listening on 127.0.0.1:36395 +[t2c:a2a] listening on 127.0.0.1:44831 +✔ A2A governed-intake skill completes accepted commands and rejects domain failures (107.276813ms) +[t2c:a2a] listening on 127.0.0.1:44327 +✔ A2A v1.0 card, versioning, task methods and cursor pagination are coherent (111.607185ms) +[t2c:a2a] listening on 127.0.0.1:44211 +✔ A2A bearer authentication is declared with v1 security objects and enforced (19.080692ms) +[t2c:a2a] listening on 127.0.0.1:39881 +[t2c:a2a] listening on 127.0.0.1:43433 +[t2c:a2a] listening on 127.0.0.1:44203 +✔ A2A file task store survives restart and preserves idempotency across replicas (89.237744ms) +✔ the A2A bind default is loopback and a wildcard bind is not mistaken for it (1.836471ms) +✔ Go adapter records package, imports, types, functions and methods (164.788519ms) +✔ Go facts are deterministic observations, not inferences (92.075434ms) +✔ Go adapter marks exported symbols and reports calls in scope (82.742285ms) +✔ Go extraction is skipped without cost when a tree holds no Go sources (12.460404ms) +✔ A missing Go toolchain degrades to a warning instead of failing the run (11.64452ms) +✔ Rust adapter records uses, types, functions, methods, values and calls (92.622354ms) +﹣ Java adapter records packages, imports, types, fields, methods and calls (7.671388ms) # JDK not installed +✔ Java and Rust adapters skip toolchain startup when no matching sources exist (22.477071ms) +✔ Missing Java and Rust toolchains degrade to explicit warnings (33.236387ms) +✔ PHP syntax adapter records namespaces, imports, types, functions, methods and calls (93.710879ms) +✔ PHP adapter skips runtime startup when no PHP source exists (10.79322ms) +✔ Missing PHP runtime degrades to an explicit warning (10.286631ms) +✔ Invalid PHP syntax is reported without aborting extraction (61.465765ms) +✔ AST extractor reads TypeScript and Python facts (230.872627ms) +✔ CLI command help is successful and non-mutating (1213.977142ms) +✔ TypeScript and Python CLIs execute the same intake command/query handler (1011.193791ms) +✔ CLI summarize exposes deterministic, prefer-llm and require-llm modes (2064.881931ms) +✔ CLI propose-todo, render-todo and apply-todo return JSON and preserve a no-op TODO (1657.687912ms) +✔ CLI watch reads TASK.md by default, disables summary LLM and reacts to a live file change (1673.517738ms) +✔ proposeCodeChangePlans materialises grounded plans from PLANNED_NOT_IMPLEMENTED (18.689764ms) +✔ code-change title preserves the leading action of a compound intent (4.588637ms) +✔ proposeCodeChangePlans is deterministic for the same evidence (3.449848ms) +✔ a plan creates a missing file and modifies an existing one (11.90513ms) +✔ a plan never invents a repository-root file from a bare filename (2.64015ms) +✔ a plan whose every path is bare and missing is withheld entirely (1.811245ms) +✔ a plan never targets a location outside the repository tree (0.183782ms) +✔ the repository probe never proposes creating a file outside the root (1.381949ms) +✔ bounded plan sets prefer explicit TODO work over historical changelog audit (2.533312ms) +✔ evaluateCodeChangeAcceptance passes when targeted diagnostics clear (7.789508ms) +✔ evaluateCodeChangeAcceptance fails while the plan is still open (2.727881ms) +✔ Plans without repository paths are not invented (0.831606ms) +✔ Non-repository paths are ignored instead of aborting code-change planning (1.19595ms) +✔ Acceptance rejects ungrounded paths, missing provenance and inconsistent verdicts (4.515004ms) +✔ createCodeChangeSourcePatch is deterministic and path-bound (5.689128ms) +✔ applyUnifiedDiffToText creates and modifies files from hunks (0.665943ms) +✔ applyCodeChangeSourcePatch requires approval and is idempotent (14.078046ms) +✔ applyCodeChangeSourcePatch preflights diffs and refuses symlink escapes (4.929948ms) +✔ createCodeChangeSourcePatchSet covers every plan (2.263136ms) +✔ createCodeChangeReviewPatch is hash-stable and lists grounded paths (2.007969ms) +✔ CLI proposes and evaluates a grounded code-change plan through persisted JSON (1706.384557ms) +✔ isUsefulCodeChangePath rejects vendored, binary and analysis dump paths (0.436789ms) +✔ proposeCodeChangePlans skips diagnostics that only name junk paths (0.993412ms) +✔ Published code-change JSON schemas require provenance, risk and rollback (2.100554ms) +✔ participant registry maps stable IDs to Git/A2A identifiers without display-name guessing (44.398001ms) +✔ participant registry rejects ambiguous external identifiers (0.934258ms) +✔ trusted intake persists roles across tickets and fails closed without rejected writes (68.628895ms) +✔ agents cannot create human projections and a damaged event hash fails verification (8.045116ms) +✔ TypeScript and dependency-free Python codecs share golden bytes and preserve unknown fields (178.03748ms) +✔ communication enrichment preserves runtime identity, source, ticket and epistemic class (54.527681ms) +✔ communication enrichment corrects one rejected structured response without weakening validation (7.142861ms) +✔ communication prefer-llm fallback is explicit and require-llm rejects (8.535948ms) +✔ project/ communication is attributed per human and agent and checked against Git evidence (230.788354ms) +✔ governance user-* and ai-* files become typed participant intent without ingesting ticket evidence (14.069188ms) +✔ unstructured governance participant content is rejected with an owner-specific migration warning (11.246946ms) +✔ opposite wording about different explicit files is not treated as an intent conflict (6.24872ms) +✔ missing response owners use explicit role sentinels without inventing participants (12.038616ms) +✔ communication extractor reports unresolved identity instead of inventing an actor (5.462402ms) +✔ communication extractor ignores generic generated analysis under project/ (5.633556ms) +✔ explicit OPENROUTER_APP_NAME overrides the project folder name (1.320154ms) +✔ missing or blank OPENROUTER_APP_NAME falls back to the resolved project folder (0.493501ms) +✔ OpenRouter application identity remains non-empty for a filesystem root (0.34502ms) +✔ configuration converter covers JSON, TOML, Docker and CI workflow declarations (36.772759ms) +✔ configuration converter emits a deterministic file aggregate for an empty configuration (6.258738ms) +✔ splitLines treats a trailing newline as a terminator, not an extra line (2.117702ms) +✔ Identical inputs produce no hunks (0.70073ms) +✔ A modified line keeps both sides addressable by original line number (0.4883ms) +✔ Pure insertion and pure deletion are not reported as replacements (0.644251ms) +✔ Empty-to-content and content-to-empty are handled as block changes (0.461993ms) +✔ Context width controls hunk size (0.410377ms) +✔ Nearby changes merge into a single hunk (0.29746ms) +✔ Distant changes stay in separate hunks (0.277068ms) +✔ Oversized inputs fall back to a bounded block replace (0.874099ms) +✔ Unified output carries a well formed hunk header (0.63102ms) +✔ Side-by-side rows pair deletions with insertions (0.384971ms) +✔ Unbalanced change runs leave one side empty rather than misaligning (0.881976ms) +✔ Renderers escape source markup (1.051878ms) +✔ SVG rendering caps rows and reports the remainder (1.939876ms) +✔ Reality view keys topics by target and records lane presence (19.00361ms) +✔ A topic holding declared and observed records is never reported as planned-only (2.825592ms) +✔ Reality coverage stays open when a shared path has unrelated capabilities (1.74771ms) +✔ Shared-path relations do not collapse unrelated files into one topic (1.924794ms) +✔ Reality view is deterministic for identical input (2.136032ms) +✔ Reality SVG escapes topic labels (1.092776ms) +✔ graph diff detects changed source identities, additions and SVG-safe labels (21.977971ms) +✔ graph diff is empty for graphs with identical evidence (2.349383ms) +✔ file diff emits deterministic unified, SVG and HTML views (2.585639ms) +✔ intent-vs-reality builds an explainable SVG and Markdown projection (5.069199ms) +✔ a targetless declaration is filed under the single module it links to (3.568584ms) +✔ a declaration touching several modules keeps its own topic (2.718437ms) +✔ a topic about a document does not absorb the statements written in it (3.289432ms) +✔ semantically aligned configuration topics retain their evidence grade (2.194005ms) +✔ A record claiming line 1 is re-anchored to the line carrying its statement (60.506427ms) +✔ An already correct line is kept and not reported as re-anchored (8.404947ms) +✔ An empty target is backfilled from the statement text (8.070333ms) +✔ A target supplied by the model is never overwritten (4.110968ms) +✔ An unclassified action and modality are derived from the statement (5.596405ms) +✔ A classified action from the model wins over the heuristic (6.734061ms) +✔ An action that stays unclassifiable is reported as a missing field (8.617175ms) +✔ A placeholder object is treated as a gap, not as content (3.782083ms) +✔ Every repair is attributable through epistemic.basis (4.077547ms) +✔ standalone source DSL facades preserve their canonical extractor results (48.348345ms) +✔ standalone source DSL facades reject invalid or foreign roots and files (1.677605ms) +✔ governed ticket README keeps wrapped goals and drops lifecycle metadata (12.821985ms) +✔ generic TASK.md line segmentation stays unchanged for headings (1.019641ms) +✔ deterministic documentation baseline records headings, code blocks and explicit references (17.0233ms) +✔ deterministic documentation preserves Polish prohibition polarity (7.285609ms) +✔ deterministic documentation resolves a unique bare filename against the repository (4.80217ms) +✔ documentation prose resolves a bare filename to its repository location (8.564907ms) +✔ a nested checkout does not shadow the repository copy of a documented file (6.497345ms) +✔ AST cache is incremental by path and source content hash (36.472394ms) +✔ AST cache rejects corrupt entries and recomputes authoritative records (9.226965ms) +✔ AST cache can be bypassed without changing extraction output (4.646758ms) +✔ successful external AST adapter is skipped on a warm manifest hit (239.187934ms) +✔ documentation chunks cache independently while provider calls remain live (41.4505ms) +✔ generated analysis replaces its source root with a stable token (70.980698ms) +✔ generated analysis root normalization refuses the filesystem root (56.452011ms) +✔ generated analysis rejects references to untracked input (105.510475ms) +✔ generated analysis accepts outputs independent of untracked input (81.154255ms) +✔ generated analysis accepts an untracked filename already quoted by tracked evidence (87.609655ms) +✔ generated analysis rejects temporary paths and unavailable validators (77.830284ms) +✔ generated README metadata is synchronized from package.json and stays idempotent (102.085183ms) +✔ generated README synchronization fails closed when the template drifts (45.542742ms) +✔ generated README synchronization rejects output outside the project root (37.05353ms) +✔ generated task and TODO projections are evidence unless communication explicitly opts in (40.545127ms) +✔ malformed front matter is rejected and non-ISO timestamps are reported (8.517091ms) +✔ assembles cited added, removed and modified truth changes (27.93068ms) +✔ keeps textual and semantic conflicts separate and cited (9.589655ms) +✔ unanchored cross-branch additions fail closed as unknown manual review (4.774822ms) +✔ duplicate changed source identities fail closed as unknown (3.79059ms) +✔ reuses one semantic bundle for refs sharing an exact tree (6.583802ms) +✔ rejects tampered Git materialization and mismatched semantic artifacts (2.10734ms) +✔ semantic bundle order and generated time do not alter portfolio identity (4.495603ms) +✔ materializes exact topology, conflicts, disjoint paths and equivalent patches read-only (605.55969ms) +✔ fingerprint is invariant to ref order and contains no clock metadata (593.557629ms) +✔ merge-tree result classifier fails closed on unavailable or ambiguous output (0.358016ms) +✔ rejects unsafe, duplicate, symbolic, missing and over-limit refs (194.586199ms) +✔ detects ref movement and removes temporary state after failure (189.236268ms) +✔ clean expected branch produces an exact deterministic PASS without changing Git state (587.309014ms) +✔ tracked, untracked and renamed paths are sorted and block a dirty workspace (387.888188ms) +✔ porcelain-v2 conflict facts and path bounds fail closed deterministically (7.625437ms) +✔ behind, detached and unexpected branches expose stable diagnostics and safe actions (750.269726ms) +✔ an ahead-only isolated branch remains usable but records a sync warning (248.258866ms) +✔ managed governance findings remain authoritative and unresolved scope blocks (246.215063ms) +✔ governance process failures keep their domain code and redact stderr (224.180298ms) +✔ implementation paths receive only the ticket selected by managed governance (246.620067ms) +✔ invalid roots, refs, checker output and options fail closed with stable codes (375.875532ms) +✔ report has no command, credential or absolute-root output and failure is read-only (283.756535ms) +✔ Git extractor emits one record per requested commit (296.384675ms) +✔ An empty repository degrades to a warning instead of failing the run (17.230371ms) +✔ versioned gold dataset reports perfect offline quality and repeated-run stability (214.240972ms) +✔ gold linking reports exact-target and capability-topic quality separately (95.821788ms) +✔ gold capability-topic support is large enough to detect a floor regression (97.765768ms) +✔ gold known gaps are measured and kept out of precision and recall (85.428885ms) +✔ gold reports cross-language positives and hard negatives as a separate cohort (108.678737ms) +✔ gold diagnostics separate a false DONE claim from an evidenced one (79.927609ms) +✔ gold v1 stays evaluable after the v2 contract extension (38.65508ms) +✔ gold loader rejects unsupported dataset versions (0.709891ms) +✔ gold evaluator rejects unknown linking cohorts (1.932842ms) +✔ gold v2 must declare diagnostics coverage (1.594718ms) +✔ published gold schema matches the runtime contract (1.925964ms) +✔ gold evaluator rejects fixture files outside its temporary workspace (9.490738ms) +✔ disjoint immutable candidates are bound to exact snapshots and merge-ready (24.301108ms) +✔ equivalent patch identity detects duplicate work across different commits (1.86676ms) +✔ textual and semantic conflicts stay separate and both block candidates (2.147134ms) +✔ contained or proven empty work is stale while unknown evidence requires review (1.267691ms) +✔ ordering and target movement produce merge-after and rebase recommendations (1.300544ms) +✔ ordering and generated time do not affect identity but a changed base does (4.528737ms) +✔ malformed identities and ungrounded semantic conflicts fail closed (1.083591ms) +✔ repository, counts, enums, digests and timestamps are validated strictly (0.749854ms) +✔ incomplete pair semantics cannot be classified as disjoint (1.039716ms) +✔ base semantic evidence and ordering citations survive projection (1.487762ms) +✔ ordering without related relation evidence fails closed (0.606953ms) +✔ missing, duplicate and self candidate pairs fail closed (0.936469ms) +✔ no unique work remains stale even when another branch has the same tree (1.069297ms) +✔ portfolio validation rejects tampering and authorization-like fields (1.527838ms) +✔ truth map groups explicit semantic evidence and preserves complete lineage (18.909988ms) +✔ structural relations do not collapse independent assertions (2.509051ms) +✔ explicit contradiction is visible and never selects a winner (1.143433ms) +✔ mixed claims remain distinct from factual support (1.044787ms) +✔ IDs and fingerprints are invariant to graph ordering and generatedAt (1.845043ms) +✔ invalid graph fingerprint and dangling relation endpoints fail closed (1.177733ms) +✔ truth map validator rejects duplicate assertion membership and reverse drift (1.172369ms) +✔ truth map validator rejects omitted mapping relations and artificial grouping (3.407339ms) +✔ Linker connects plan, Git claim and AST fact (21.794457ms) +✔ Linker connects prose intent to a module through three grounded capability topics (1.517687ms) +✔ Linker does not connect a module on one generic topic alone (1.132814ms) +✔ An existing target path does not prove an unrelated capability (2.620057ms) +✔ An existing target path plus an AST capability proves implementation (1.576551ms) +✔ Diagnostics distinguish descriptive documentation from prescriptive requirements (2.932212ms) +✔ A changelog entry naming an extracted documentation file has release evidence (1.499874ms) +✔ Diagnostics ignore non-actionable changelog mechanics but retain release claims (4.617413ms) +✔ Grounded conclusion and TODO proposal contracts accept traceable values (11.866228ms) +✔ Stable IDs ignore ordering noise but change with semantic content (1.188753ms) +✔ Validators reject ungrounded citations and stale semantic IDs (2.83374ms) +✔ Generation metadata exposes LLM failures instead of silently masking them (1.803318ms) +✔ TODO proposal collections enforce dependency integrity (1.435148ms) +✔ Published JSON schemas identify all grounded output contract versions (36.770405ms) +✔ Blank lines and comments produce no rules (2.140916ms) +✔ A pattern without a slash matches at any depth (0.649706ms) +✔ A leading slash anchors the pattern to the root (0.303943ms) +✔ A trailing slash restricts the rule to directories (0.26374ms) +✔ Wildcards respect path separators (0.741879ms) +✔ Every dot-directory is excluded by `.*/` (0.380055ms) +✔ Negation re-includes a previously excluded path (0.431851ms) +✔ Negation cannot resurrect a file inside an excluded directory (0.409691ms) +✔ Last matching rule wins (0.400642ms) +✔ Character classes are supported (0.497762ms) +✔ Paths are normalised before matching (0.41833ms) +✔ loadIgnoreMatcher merges the three ignore files and skips missing ones (23.014564ms) +✔ A repository without ignore files excludes nothing (1.199085ms) +✔ The shipped .intentignore excludes build output but keeps sources (2.816769ms) +✔ resolveGlobs permits one explicit .intent report without recursively scanning generated runs (8.330116ms) +✔ Two unrelated AST facts sharing only a file are not linked (17.684057ms) +✔ AST facts sharing a symbol are still linked despite the path rule (1.914585ms) +✔ AST details sharing only a file and generic tokens do not create a quadratic subgraph (4.106786ms) +✔ A file-level plan links once to the AST module aggregate instead of every detail (7.4201ms) +✔ A shared path still links a plan to an AST fact (1.233393ms) +✔ A bare filename links to a module only when its repository path is unique (1.722148ms) +✔ A bare filename refuses ambiguous module paths (2.155168ms) +✔ Relations that carry a conclusion survive alongside suppressed noise (2.357214ms) +✔ Pair ordering stays deterministic across rebuilds (3.887036ms) +✔ Two configuration declarations sharing only a key name are not linked (0.848305ms) +✔ A shared ticket still connects two configuration declarations (0.608686ms) +✔ Configuration still links to documentation that describes it (0.620067ms) +✔ Configuration file aggregate is the file-level target for an explicit documentation path (0.799976ms) +✔ Configuration aggregates do not create broad capability-topic links (0.483491ms) +✔ a full six-stage live run passes and reports every stage (3.88655ms) +✔ a stage that silently fell back to deterministic fails the check (0.555319ms) +✔ a missing stage cannot pass as covered (0.339809ms) +✔ per-stage and total budgets are enforced separately (0.547755ms) +✔ live request timeout reaches the stage budget without shortening a larger override (0.259404ms) +✔ a stage reason is recorded with provider text redacted (0.704654ms) +✔ history records the trend without gating on it (0.456357ms) +✔ recorded audit history includes the current run exactly once (0.71246ms) +✔ history stays chronological, bounded and free of duplicate runs (11.462379ms) +✔ an audit converts to exactly the redacted fields history keeps (0.543451ms) +✔ an empty history summarizes without pretending to have measured anything (0.232294ms) +✔ a batched run is measured per record, not per request (5.591756ms) +✔ a model whose response the validator rejected is not counted as enriched (0.368536ms) +✔ a failed model is a comparison result rather than a crash (1.259028ms) +✔ agreement compares only records both models enriched (0.522245ms) +✔ agreement is absent rather than perfect when nothing overlaps (0.794974ms) +✔ the rendered comparison names the cheapest and fastest passing model (0.462596ms) +✔ semantic LLM modes default to require-llm (1.24392ms) +✔ Markdown extractor separates TODO plans and changelog claims (21.381831ms) +✔ Markdown extractor preserves indented continuation lines and their source range (6.453611ms) +✔ TODO bare filenames inherit an existing directory from the heading scope (2.487599ms) +✔ TODO resolves a bare filename only when its repository basename is unique (2.471167ms) +✔ TODO and CHANGELOG resolve the same bare filename to one repository path (2.994435ms) +✔ CHANGELOG keeps an ambiguous bare filename unresolved (2.075403ms) +✔ Markdown path resolution drops paths and heading scopes outside the repository (1.700593ms) +✔ TODO and CHANGELOG receive audited LLM enrichment without changing structural facts (33.439826ms) +✔ Markdown enrichment corrects one rejected response and audits both attempts (6.679464ms) +✔ large Markdown enrichment uses bounded concurrency and keeps provider audits ordered (52.650886ms) +✔ TODO and CHANGELOG LLM fallback and require mode are explicit (2.824469ms) +✔ TODO and CHANGELOG reject structurally invalid LLM enrichments (4.011043ms) +✔ a truncated batch is split and every record keeps its own response provenance (6.573308ms) +✔ a malformed batch response splits instead of failing the whole stage (5.365997ms) +✔ MCP 2026 profile is stateless and exposes discovery plus complete results (6.999997ms) +✔ MCP 2026 rejects missing metadata and unsupported versions with protocol errors (1.912433ms) +✔ MCP legacy profile negotiates 2025-11-25 and requires initialize (0.633952ms) +✔ MCP exposes annotated intake command/query tools backed by the domain handler (22.666438ms) +✔ An LLM record is marked as inference and keeps runtime-owned provenance (33.315083ms) +✔ NL extraction corrects one rejected structured response and audits both attempts (4.610396ms) +✔ Confidence must satisfy the provider schema instead of being silently clamped (9.730986ms) +✔ Source lines are clamped to the real file (2.846854ms) +✔ A placeholder object is recorded as a missing field, not as content (14.556836ms) +✔ A real object is kept verbatim and reports no missing field (2.195636ms) +✔ The explicit unknown action is reported as a missing field (4.184868ms) +✔ Both gaps are reported together (5.296351ms) +✔ Out-of-vocabulary enums are rejected instead of changing the provider intent (10.470859ms) +✔ Rejected NL output keeps provider metadata in the failed audit (4.326256ms) +✔ The documented confidence hierarchy holds across LLM extractors (1.725991ms) +✔ NL extractor produces deterministic non-LLM records (13.280164ms) +✔ NL public extraction boundary names a missing sourcePath before path resolution (1.129294ms) +✔ deterministic NL fallback skips Markdown headings and recognizes comparison intent (3.853358ms) +✔ path extraction rejects lowercase prose alternations without losing repository paths (1.452143ms) +✔ path extraction rejects dotted DSL fields but keeps known file extensions (0.344208ms) +✔ detectModality ignores parenthetical labels and bare adjectives (0.515136ms) +✔ detectModality reads prohibitions and periphrastic obligation as requirements (0.828531ms) +✔ detectPolarity does not treat without-complements as sentence negation (0.267602ms) +✔ path extraction rejects HTTP routes, host paths and parent traversal (0.273443ms) +✔ symbol extraction rejects hostnames without losing qualified code symbols (0.512169ms) +✔ symbol extraction separates repository files and all-caps prose from code identifiers (0.277992ms) +✔ topic keywords normalize paths, camelCase and documentation word forms (1.279111ms) +✔ NL LLM extraction emits audited provenance and bounded DSL records (59.605012ms) +✔ NL LLM failure is explicit when deterministic fallback is used (8.786948ms) +✔ require-llm rejects instead of silently falling back (0.581126ms) +✔ adaptive OpenRouter timeout scales at exact power-of-two boundaries (1.577845ms) +✔ output budget and structural complexity independently scale timeout (0.493204ms) +✔ adaptive OpenRouter timeout caps at ten minutes (0.211764ms) +✔ adaptive OpenRouter timeout rejects malformed and unbounded inputs (2.292769ms) +✔ OpenRouter audit records the non-secret adaptive timeout policy (1.639711ms) +✔ external cancellation remains immediate before an OpenRouter fetch (1.325686ms) +✔ retry backoff remains inside one effective OpenRouter deadline (36.807114ms) +✔ OpenRouter client parses structured JSON without exposing key (25.49874ms) +✔ OpenRouter client preserves metadata when runtime rejects structured output (1.76095ms) +✔ OpenRouter client lists available models after an invalid model ID (11.835626ms) +✔ OpenRouter client redacts provider key-management evidence while retaining the failure reason (1.115762ms) +✔ OpenRouter model-list failures redact credentials and contextual credential identifiers (0.81135ms) +✔ OpenRouter JSON timeout is not repeated as a schema fallback request (0.740648ms) +✔ OpenRouter request obeys a shared pipeline deadline without retrying (0.742556ms) +✔ Documentation extractor converts OpenRouter structured output to bounded LLM records (20.145928ms) +✔ Documentation extractor reports and enforces its chunk budget (8.478364ms) +✔ Documentation extractor corrects one rejected chunk and audits both responses (6.171852ms) +✔ Documentation extractor does not spend its correction retry on a timeout (7.254452ms) +✔ Documentation extractor exposes an audited configuration failure (0.509738ms) +✔ Documentation extractor uses bounded concurrent OpenRouter requests (35.272875ms) +✔ LLM summarizer receives graph data and preserves grounded record citations (10.516584ms) +✔ LLM summarizer validates provider fields before creating semantic IDs (4.867308ms) +✔ LLM summarizer diagnoses a provider that ignores the response envelope (2.731741ms) +✔ LLM summarizer rejects diagnostic citations outside the supplied graph (4.611481ms) +✔ LLM summarizer prioritizes documentation over the AST payload budget (140.512506ms) +✔ deterministic summary presents AST module aggregates instead of low-level calls (3.217745ms) +✔ The summarizer grounds a fabricated record citation from its diagnostic (5.464393ms) +✔ The summarizer still fails when the retry fabricates a diagnostic again (3.340624ms) +✔ variable contracts and operation plans have deterministic content-bound IDs (7.501365ms) +✔ every variable grants Founder read/write authority and immutable variables reject other writers (1.079595ms) +✔ plans reject undeclared parameters, actor visibility gaps and payload secrets (1.504005ms) +✔ safety-sensitive commands require a Founder decision, a human boundary and verification (0.901922ms) +✔ plan hash detects semantic tampering (1.524756ms) +✔ compiler emits the exact governed envelope without an execution surface (1.607736ms) +✔ runtime draft boundaries ignore lifecycle and identity fields injected by untyped callers (0.759087ms) +✔ compiler fails closed on extra, stale, wrong-source and wrong-type bindings (1.486864ms) +✔ file boundary writes one private envelope atomically and refuses overwrite (11.522017ms) +✔ canonical ticket-045 fixture parses and renders byte-for-byte (18.713026ms) +✔ identical semantic inputs render identically and sort by canonical recording order (1.298696ms) +✔ parser fails closed on tampered chains and non-canonical encoding (1.063183ms) +✔ unsafe evidence, secrets and advisory approval are rejected before rendering (0.525925ms) +✔ writer publishes one validated file atomically and refuses an immutable overwrite (7.070554ms) +✔ Offline pipeline writes a complete run (188.649744ms) +✔ Pipeline writes a canonical event log for a successful deterministic run (27.009347ms) +✔ Pipeline persists synthesis, validation and review patch, then registers approval receipt (38.98071ms) +✔ Pipeline integrates multi-participant communication into graph, diagnostics, reality and run artifacts (57.836166ms) +✔ Pipeline require-llm task synthesis failure is audited and never publishes latest (24.230319ms) +✔ Pipeline persists an audited failure when communication require-llm cannot run (23.802357ms) +✔ Pipeline persists communication stage failure and does not publish latest (23.30599ms) +✔ Pipeline persists a failed manifest when NL require-llm aborts (16.969919ms) +✔ Pipeline persists a failed manifest when Markdown require-llm aborts (21.429229ms) +✔ Pipeline persists a failed manifest for an unexpected summary failure (27.071689ms) +✔ descriptive update intents do not create missing nested paths (24.940327ms) +✔ Proposal validation reports existing TODO duplicates and orders dependencies before priority (16.689697ms) +✔ Proposal validation rejects dependency cycles and whitespace-only criterion duplicates (2.312238ms) +✔ Python package executes the local TypeScript reality runtime without a server (1602.674386ms) +✔ runtime cycle extractor turns probes, violations, drift and proposals into records (17.022854ms) +✔ measurements enter as fact and the cycle own suggestions as inference (2.715198ms) +✔ a violated expectation is negative and blocked, a healthy probe positive and verified (4.711934ms) +✔ a probe that could not run is unknown, not failing (2.342442ms) +✔ a watched path lets a runtime fact link to the code that produces it (23.975376ms) +✔ a document that is not an autonom cycle is refused by schema, not silently empty (2.289051ms) +✔ Runtime validator enforces the complete Intent DSL enum and object contract (5.272424ms) +✔ Linker and remote action boundary reject malformed records before graph construction (7.105535ms) +✔ Graph validator rejects invalid relations and inconsistent statistics (2.778527ms) +[t2c:a2a] listening on 127.0.0.1:36335 +✔ diff UI and TypeScript/Python SDKs use the live backend runtime (392.562965ms) +✔ MCP/A2A action boundary rejects traversal and symlink escapes (30.763691ms) +✔ bounded retrieval cannot create a relation until a grounded reranker accepts it (21.448006ms) +✔ reranker fails closed on ungrounded quotes and more than one accepted module (3.591252ms) +✔ OpenRouter reranking is required, structured and reusable only through an identity-bound cache (84.697515ms) +✔ published semantic reranker schemas expose the versioned bounded contracts (1.506226ms) +✔ provider response validation diagnoses the exact property without coercion (0.595676ms) +✔ analysis policy renders and parses one canonical byte representation (2.84435ms) +✔ deterministic triggers select required LLM stages and exact usage ceilings (0.463963ms) +✔ selection rejects unknown, duplicate and non-canonical trigger input (0.549942ms) +✔ policy and exact-evidence cache fingerprints bind every semantic input (2.252087ms) +✔ token ceilings convert to a deterministic provider-rate cost bound (0.26877ms) +✔ policy rejects semantic fallback and non-exact cache modes (0.320177ms) +✔ stage topology and nested budgets fail closed (0.667042ms) +✔ parser rejects non-canonical and structurally ambiguous text (0.498981ms) +✔ one structured contract emits the provider schema and parses the same value (1.767231ms) +✔ structured parsing fails closed with the exact response path (1.556418ms) +✔ object uniqueness uses canonical JSON identity rather than property order (0.275588ms) +✔ SubLLM bridge resolves the selected central route without command-shell interpolation (394.555118ms) +✔ todo2code sends structured semantic requests through direct Z.AI resolved by SubLLM (565.577749ms) +✔ explicitly requested SubLLM fails closed when its package is unavailable (2.929096ms) +✔ a short NL symbol resolves to its only AST owner (17.130563ms) +✔ an ambiguous short NL symbol does not pretend that either AST owner is selected (3.235025ms) +✔ an explicit path selects one owner of an otherwise ambiguous symbol (1.533617ms) +✔ a qualified symbol selects its exact AST declaration without a path (1.090335ms) +✔ a symbol and explicit path conflict reports the observed AST location (1.908629ms) +✔ missingFields diagnostics prescribe a concrete edit for every known gap (0.618035ms) +✔ Target normalization canonicalizes paths, symbols and cross-language separators (1.855085ms) +✔ Qualified AST symbols align with short plan and documentation targets (15.367323ms) +✔ Structured task synthesis materializes stable, grounded contracts with a complete audit (46.338615ms) +✔ blank response-local proposal keys are rejected instead of invented by the runtime (4.104293ms) +✔ prefer-llm exposes raw diagnostic actions without claiming semantic task generation (1.043686ms) +✔ communication divergence is grounded in task synthesis without treating agent claims as facts (6.512109ms) +✔ task synthesis defaults to require-llm and fails explicitly without a provider (1.057769ms) +✔ invalid structured LLM citations are rejected or visibly degraded according to mode (7.071161ms) +✔ task synthesis timeout is audited and never retried as a format fallback (13.24173ms) +✔ A fabricated record citation is grounded from its cited diagnostic without a retry (4.821135ms) +✔ A fabricated diagnostic still fails after the corrective retry (4.370664ms) +✔ TensorFlow remains an explicit fallback when the isolated adapter is not installed (6.069329ms) +✔ TODO patch rendering is stable, dependency-first and excludes classified duplicates (25.281156ms) +✔ empty and duplicate-only results render an explicit no-op patch (3.742527ms) +✔ apply rejects missing or wrong approval, stale TODO and a tampered patch (21.409461ms) +✔ approved apply is atomic, receipt-backed and idempotent (14.801688ms) +✔ service actions execute LLM propose -> render -> approved apply with scoped artifacts (75.084492ms) +✔ scanTree prunes ignored directories and records file signatures (25.722548ms) +✔ diffSnapshots classifies additions, modifications and removals (0.552ms) +✔ describeDelta truncates long change lists (0.181702ms) +✔ An unchanged tree produces exactly one report and then stays quiet (7.177827ms) +✔ Reports are rate limited to one per interval no matter how often files change (42.357252ms) +✔ A change is reported once the interval has elapsed (7.456206ms) +✔ Ignored files never trigger a report (5.660068ms) +✔ A failing report is surfaced and does not stop the watcher (2.053198ms) +✔ --no-initial-report waits for a real change (1.197151ms) +✔ Communication changes trigger watch and coalesce under the existing report rate limit (6.630134ms) +✔ workflow verifier rejects duplicate top-level YAML keys (218.348456ms) +✔ workspace preflight help and required input fail before repository inspection (200.148423ms) +✔ workspace preflight maps canonical PASS and BLOCKED reports without Git mutation (763.701067ms) +✔ Make quotes caller input as one argument in its preflight recipe (3.077372ms) +✔ Make preflight reserves stdout for one canonical report (5517.280077ms) +✔ GitHub event collector maps supported push payloads to canonical event logs (57.903571ms) +✔ GitHub review events are SYSTEM_FACT and cannot become approval attestation (39.774952ms) +✔ GitHub review with unsupported state fails closed (43.127106ms) +✔ Evidence projection is allowlisted and extra payload fields do not leak into logs (83.902626ms) +✔ GitHub acquisition ignores ambient environment and requires explicit input (117.538192ms) +✔ workspace comparison deadline scales aggregate input and LLM work in bounded 2x steps (1.459835ms) +✔ workspace headline trend ignores AST-only topic and source churn (0.305179ms) +✔ workspace comparison measures origin/main against uncommitted filesystem intent (458.274201ms) +ℹ tests 425 +ℹ suites 0 +ℹ pass 424 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 1 +ℹ todo 0 +ℹ duration_ms 15740.01474 +GOV-PASS: passed (0 errors, 0 warnings) diff --git a/project/ticket-079/ai-gpt-5.6-sol.md b/project/ticket-079/ai-gpt-5.6-sol.md new file mode 100644 index 0000000..0631cbc --- /dev/null +++ b/project/ticket-079/ai-gpt-5.6-sol.md @@ -0,0 +1,28 @@ +--- +participant-id: agent:gpt-5.6-sol +participant: gpt-5.6-sol +role: agent +ticket: ticket-079 +--- +# Participant: gpt-5.6-sol (AI agent) + +## Understanding + +Descriptive documentation intents that mention missing nested paths were turned +into invented `create` plans. Create must require explicit add/create intent. + +## Execution plan + +1. Gate missing nested-path `create` on explicit create intent. +2. Cover descriptive vs explicit cases in an llm-owned test file. +3. Prove with tests and governance after ticket-078 is committed. + +## Actual changes + +- `src/synthesis/code-change-plan-propose.ts`: `hasExplicitCreateIntent`. +- `test/plan-create-llm.test.ts`: descriptive withhold vs explicit create. + +## Blockers + +- Combined dirty tree with unfinished ticket-078 files may block governance + until ticket-078 is committed. diff --git a/project/ticket-079/changelog.md b/project/ticket-079/changelog.md new file mode 100644 index 0000000..0843718 --- /dev/null +++ b/project/ticket-079/changelog.md @@ -0,0 +1,7 @@ +# Ticket Changelog (ticket-079) + +## [0.1.0] - 2026-08-17 + +- Withhold missing nested-path `create` plans unless source explicitly asks to + add/create/implement. +- Add llm-owned coverage in `test/plan-create-llm.test.ts`. diff --git a/project/ticket-079/intent.json b/project/ticket-079/intent.json new file mode 100644 index 0000000..ea08ac3 --- /dev/null +++ b/project/ticket-079/intent.json @@ -0,0 +1,91 @@ +{ + "schema": "new-project.intent/v3", + "ticket": "ticket-079", + "summary": "Withhold invented create plans for missing nested paths", + "workstream": "llm", + "classification": { + "kind": "FEATURE", + "priority": "P1", + "origin": "requested" + }, + "allowedPaths": [ + "project/ticket-079/**", + "TODO.md", + "project/TICKETS.md", + "src/synthesis/code-change-plan-propose.ts", + "test/plan-create-llm.test.ts" + ], + "forbiddenPaths": [ + "project/ticket-*/user-*.md", + "src/extractors/**", + "src/core/**", + "test/code-change-plan.test.ts" + ], + "stacks": [ + "node" + ], + "dependsOn": [ + "ticket-078" + ], + "conflictsWith": [], + "integrationTicket": null, + "delivery": { + "acceptedBaseSha": "46fa4ce01a7e7a6d679cbb8dac3ead29abceac28", + "targetBranch": "main", + "outcome": "Deterministic code-change plans propose create for missing nested paths only when the source intent explicitly asks to add, create, or implement.", + "nonGoals": [ + "No NL ticket README changes", + "No runtime version bump", + "No edits to the existing runtime-owned code-change-plan.test.ts" + ], + "complexity": "S", + "estimatedMinutes": 20, + "budgets": { + "maxImplementationFiles": 2, + "maxAffectedComponents": 1, + "maxPublicInterfaceChanges": 0, + "maxRuntimeDependencies": 0 + }, + "architecture": { + "status": "accepted", + "decision": "Gate missing-path create actions on explicit add/create/implement intent inside proposeCodeChangePlans.", + "components": [ + { + "name": "safe-code-change-planning", + "paths": [ + "src/synthesis/code-change-plan-propose.ts", + "test/plan-create-llm.test.ts" + ] + } + ], + "responsibilityChanges": false, + "interfaceChanges": [], + "dataChanges": [], + "ui": { + "impact": "none", + "states": [], + "evidence": [] + }, + "rollback": "Restore prior missing-path create inference without explicit create intent." + }, + "runtimeDependencies": [], + "validation": [ + { + "criterion": "AC-01", + "commands": [ + "npm run check", + "npm run build", + "npm test" + ], + "evidence": "project/ticket-079/ai-gpt-5.6-sol-logs.txt" + }, + { + "criterion": "AC-02", + "commands": [ + "./project/governance-check.sh --actor agent" + ], + "evidence": "project/ticket-079/ai-gpt-5.6-sol-logs.txt" + } + ] + } +} diff --git a/project/ticket-079/preprompt.md b/project/ticket-079/preprompt.md new file mode 100644 index 0000000..0112eef --- /dev/null +++ b/project/ticket-079/preprompt.md @@ -0,0 +1,8 @@ +# Ticket preprompt + +- **Task ID**: ticket-079 +- **Task title**: Withhold invented create plans for missing nested paths +- **Created**: 2026-08-17T11:04:52Z + +Keep executable implementation outside this governance/evidence directory. +Read a human-owned user-*.md file only when one exists. diff --git a/project/ticket-080/README.md b/project/ticket-080/README.md new file mode 100644 index 0000000..273f31f --- /dev/null +++ b/project/ticket-080/README.md @@ -0,0 +1,29 @@ +# Ticket 080: Bind runtime version assertions to T2C_VERSION + +- **ID**: ticket-080 +- **Owner**: unresolved:human +- **Status**: DONE +- **Workflow state**: DONE +- **Created**: 2026-08-17 + +## Goal and scope + +Replace hardcoded `0.5.0` runtime version assertions in runtime-owned tests +with the shared `T2C_VERSION` constant so a later core-dsl version bump does +not require cross-workstream test edits. + +## Acceptance criteria + +- [x] AC-01: `test/pipeline.test.ts` and `test/code-change-plan.test.ts` assert + against `T2C_VERSION`. +- [x] AC-02: Build, tests and governance pass for the runtime scope. + +## Participants + +- Human participant: unresolved; no user-* file was created by this script. +- Agent participant: [ai-gpt-5.6-sol.md](ai-gpt-5.6-sol.md) + +## SESSION_EXECUTION_AUTHORIZATION + +The user's instruction to continue outstanding work and push authorizes this +bounded runtime assertion fix. diff --git a/project/ticket-080/ai-gpt-5.6-sol-logs.txt b/project/ticket-080/ai-gpt-5.6-sol-logs.txt new file mode 100644 index 0000000..1bda45e --- /dev/null +++ b/project/ticket-080/ai-gpt-5.6-sol-logs.txt @@ -0,0 +1 @@ +GOV-PASS: passed (0 errors, 0 warnings) diff --git a/project/ticket-080/ai-gpt-5.6-sol.md b/project/ticket-080/ai-gpt-5.6-sol.md new file mode 100644 index 0000000..18848ca --- /dev/null +++ b/project/ticket-080/ai-gpt-5.6-sol.md @@ -0,0 +1,12 @@ +--- +participant-id: agent:gpt-5.6-sol +participant: gpt-5.6-sol +role: agent +ticket: ticket-080 +--- +# Participant: gpt-5.6-sol (AI agent) + +## Actual changes + +- Bound `test/pipeline.test.ts` and `test/code-change-plan.test.ts` provenance + assertions to `T2C_VERSION`. diff --git a/project/ticket-080/changelog.md b/project/ticket-080/changelog.md new file mode 100644 index 0000000..52602a8 --- /dev/null +++ b/project/ticket-080/changelog.md @@ -0,0 +1,5 @@ +# Ticket Changelog (ticket-080) + +## [0.1.0] - 2026-08-17 + +- Runtime-owned tests assert against `T2C_VERSION` instead of `0.5.0`. diff --git a/project/ticket-080/intent.json b/project/ticket-080/intent.json new file mode 100644 index 0000000..462b172 --- /dev/null +++ b/project/ticket-080/intent.json @@ -0,0 +1,78 @@ +{ + "schema": "new-project.intent/v3", + "ticket": "ticket-080", + "summary": "Bind runtime version assertions to T2C_VERSION", + "workstream": "runtime", + "classification": { + "kind": "BUG", + "priority": "P1", + "origin": "regression" + }, + "allowedPaths": [ + "project/ticket-080/**", + "TODO.md", + "project/TICKETS.md", + "test/pipeline.test.ts", + "test/code-change-plan.test.ts" + ], + "forbiddenPaths": [ + "project/ticket-*/user-*.md", + "src/**" + ], + "stacks": [ + "node" + ], + "dependsOn": [], + "conflictsWith": [], + "integrationTicket": null, + "delivery": { + "acceptedBaseSha": "35cd2c0d1ef3430d794f1fea72d07eed0efe3af3", + "targetBranch": "main", + "outcome": "Runtime-owned tests assert against T2C_VERSION instead of a hardcoded 0.5.0 literal.", + "nonGoals": [ + "No version.ts change", + "No SDK or live fixture rewrites" + ], + "complexity": "XS", + "estimatedMinutes": 10, + "budgets": { + "maxImplementationFiles": 2, + "maxAffectedComponents": 1, + "maxPublicInterfaceChanges": 0, + "maxRuntimeDependencies": 0 + }, + "architecture": { + "status": "accepted", + "decision": "Replace hardcoded runtime version literals in runtime-owned tests with the shared T2C_VERSION constant.", + "components": [ + { + "name": "runtime-version-assertions", + "paths": [ + "test/pipeline.test.ts", + "test/code-change-plan.test.ts" + ] + } + ], + "responsibilityChanges": false, + "interfaceChanges": [], + "dataChanges": [], + "ui": { + "impact": "none", + "states": [], + "evidence": [] + }, + "rollback": "Restore hardcoded 0.5.0 assertions." + }, + "runtimeDependencies": [], + "validation": [ + { + "criterion": "AC-01", + "commands": [ + "npm run build", + "npm test" + ], + "evidence": "project/ticket-080/ai-gpt-5.6-sol-logs.txt" + } + ] + } +} diff --git a/project/ticket-080/preprompt.md b/project/ticket-080/preprompt.md new file mode 100644 index 0000000..b35bc7d --- /dev/null +++ b/project/ticket-080/preprompt.md @@ -0,0 +1,8 @@ +# Ticket preprompt + +- **Task ID**: ticket-080 +- **Task title**: Bind runtime version assertions to T2C_VERSION +- **Created**: 2026-08-17T11:13:02Z + +Keep executable implementation outside this governance/evidence directory. +Read a human-owned user-*.md file only when one exists. diff --git a/project/ticket-081/README.md b/project/ticket-081/README.md new file mode 100644 index 0000000..3d6b3eb --- /dev/null +++ b/project/ticket-081/README.md @@ -0,0 +1,24 @@ +# Ticket 081: Bind Python runtime version assertion to T2C_VERSION + +- **ID**: ticket-081 +- **Owner**: unresolved:human +- **Status**: DONE +- **Workflow state**: DONE +- **Created**: 2026-08-17 + +## Goal and scope + +Bind the Python SDK bridge version assertion to `T2C_VERSION`. + +## Acceptance criteria + +- [x] AC-01: `test/python-runtime.test.ts` asserts against `T2C_VERSION`. +- [x] AC-02: Build, tests and governance pass for the sdk scope. + +## Participants + +- Agent participant: [ai-gpt-5.6-sol.md](ai-gpt-5.6-sol.md) + +## SESSION_EXECUTION_AUTHORIZATION + +The user's instruction to continue outstanding work and push authorizes this fix. diff --git a/project/ticket-081/ai-gpt-5.6-sol-logs.txt b/project/ticket-081/ai-gpt-5.6-sol-logs.txt new file mode 100644 index 0000000..e9e9c22 --- /dev/null +++ b/project/ticket-081/ai-gpt-5.6-sol-logs.txt @@ -0,0 +1,10 @@ +✔ Python package executes the local TypeScript reality runtime without a server (1488.498238ms) +ℹ tests 1 +ℹ suites 0 +ℹ pass 1 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 1579.229827 +GOV-PASS: passed (0 errors, 0 warnings) diff --git a/project/ticket-081/ai-gpt-5.6-sol.md b/project/ticket-081/ai-gpt-5.6-sol.md new file mode 100644 index 0000000..dfc2353 --- /dev/null +++ b/project/ticket-081/ai-gpt-5.6-sol.md @@ -0,0 +1,9 @@ +--- +participant-id: agent:gpt-5.6-sol +participant: gpt-5.6-sol +role: agent +ticket: ticket-081 +--- +# Participant: gpt-5.6-sol + +Bound `test/python-runtime.test.ts` to `T2C_VERSION`. diff --git a/project/ticket-081/changelog.md b/project/ticket-081/changelog.md new file mode 100644 index 0000000..f6720cf --- /dev/null +++ b/project/ticket-081/changelog.md @@ -0,0 +1,5 @@ +# Ticket Changelog (ticket-081) + +## [0.1.0] - 2026-08-17 + +- Python runtime bridge test asserts against `T2C_VERSION`. diff --git a/project/ticket-081/intent.json b/project/ticket-081/intent.json new file mode 100644 index 0000000..410e721 --- /dev/null +++ b/project/ticket-081/intent.json @@ -0,0 +1,62 @@ +{ + "schema": "new-project.intent/v3", + "ticket": "ticket-081", + "summary": "Bind Python runtime version assertion to T2C_VERSION", + "workstream": "sdk", + "classification": { + "kind": "BUG", + "priority": "P1", + "origin": "regression" + }, + "allowedPaths": [ + "project/ticket-081/**", + "TODO.md", + "project/TICKETS.md", + "test/python-runtime.test.ts" + ], + "forbiddenPaths": [ + "project/ticket-*/user-*.md", + "src/**" + ], + "stacks": ["node", "python"], + "dependsOn": [], + "conflictsWith": [], + "integrationTicket": null, + "delivery": { + "acceptedBaseSha": "f966afdaa6fbe28da4a2a1d3e686c5f58da491ca", + "targetBranch": "main", + "outcome": "Python SDK bridge test asserts against T2C_VERSION.", + "nonGoals": ["No version.ts change"], + "complexity": "XS", + "estimatedMinutes": 8, + "budgets": { + "maxImplementationFiles": 1, + "maxAffectedComponents": 1, + "maxPublicInterfaceChanges": 0, + "maxRuntimeDependencies": 0 + }, + "architecture": { + "status": "accepted", + "decision": "Bind the Python runtime bridge version assertion to T2C_VERSION.", + "components": [ + { + "name": "python-runtime-bridge-test", + "paths": ["test/python-runtime.test.ts"] + } + ], + "responsibilityChanges": false, + "interfaceChanges": [], + "dataChanges": [], + "ui": {"impact": "none", "states": [], "evidence": []}, + "rollback": "Restore hardcoded 0.5.0 assertion." + }, + "runtimeDependencies": [], + "validation": [ + { + "criterion": "AC-01", + "commands": ["npm run build", "npm test"], + "evidence": "project/ticket-081/ai-gpt-5.6-sol-logs.txt" + } + ] + } +} diff --git a/project/ticket-081/preprompt.md b/project/ticket-081/preprompt.md new file mode 100644 index 0000000..f2eb071 --- /dev/null +++ b/project/ticket-081/preprompt.md @@ -0,0 +1,8 @@ +# Ticket preprompt + +- **Task ID**: ticket-081 +- **Task title**: Bind Python runtime version assertion to T2C_VERSION +- **Created**: 2026-08-17T11:14:03Z + +Keep executable implementation outside this governance/evidence directory. +Read a human-owned user-*.md file only when one exists. diff --git a/project/ticket-082/README.md b/project/ticket-082/README.md new file mode 100644 index 0000000..7432c34 --- /dev/null +++ b/project/ticket-082/README.md @@ -0,0 +1,25 @@ +# Ticket 082: Align T2C_VERSION with package 0.5.1 + +- **ID**: ticket-082 +- **Owner**: unresolved:human +- **Status**: DONE +- **Workflow state**: DONE +- **Created**: 2026-08-17 + +## Goal and scope + +Set `T2C_VERSION` to `0.5.1` so generated provenance matches `package.json`. + +## Acceptance criteria + +- [x] AC-01: `src/core/version.ts` reports `0.5.1`. +- [x] AC-02: Build, tests and governance pass for the core-dsl scope. + +## Participants + +- Agent participant: [ai-gpt-5.6-sol.md](ai-gpt-5.6-sol.md) + +## SESSION_EXECUTION_AUTHORIZATION + +The user's instruction to continue outstanding work and push authorizes this +version identity correction after tickets 080 and 081. diff --git a/project/ticket-082/ai-gpt-5.6-sol-logs.txt b/project/ticket-082/ai-gpt-5.6-sol-logs.txt new file mode 100644 index 0000000..d3912ed --- /dev/null +++ b/project/ticket-082/ai-gpt-5.6-sol-logs.txt @@ -0,0 +1,446 @@ + +> todo2code@0.5.1 test +> node --test --test-concurrency=4 dist/test/*.test.js + +[t2c:a2a] listening on 127.0.0.1:39369 +[t2c:a2a] listening on 127.0.0.1:36951 +✔ A2A governed-intake skill completes accepted commands and rejects domain failures (106.8812ms) +[t2c:a2a] listening on 127.0.0.1:34689 +✔ A2A v1.0 card, versioning, task methods and cursor pagination are coherent (103.375268ms) +[t2c:a2a] listening on 127.0.0.1:34221 +✔ A2A bearer authentication is declared with v1 security objects and enforced (20.893888ms) +[t2c:a2a] listening on 127.0.0.1:33981 +[t2c:a2a] listening on 127.0.0.1:44031 +[t2c:a2a] listening on 127.0.0.1:38231 +✔ A2A file task store survives restart and preserves idempotency across replicas (95.744537ms) +✔ the A2A bind default is loopback and a wildcard bind is not mistaken for it (2.233981ms) +✔ Go adapter records package, imports, types, functions and methods (141.394265ms) +✔ Go facts are deterministic observations, not inferences (114.211922ms) +✔ Go adapter marks exported symbols and reports calls in scope (118.248296ms) +✔ Go extraction is skipped without cost when a tree holds no Go sources (12.609415ms) +✔ A missing Go toolchain degrades to a warning instead of failing the run (11.020522ms) +✔ Rust adapter records uses, types, functions, methods, values and calls (98.863537ms) +﹣ Java adapter records packages, imports, types, fields, methods and calls (7.122811ms) # JDK not installed +✔ Java and Rust adapters skip toolchain startup when no matching sources exist (19.252776ms) +✔ Missing Java and Rust toolchains degrade to explicit warnings (19.611715ms) +✔ PHP syntax adapter records namespaces, imports, types, functions, methods and calls (123.896838ms) +✔ PHP adapter skips runtime startup when no PHP source exists (19.91337ms) +✔ Missing PHP runtime degrades to an explicit warning (17.945901ms) +✔ Invalid PHP syntax is reported without aborting extraction (90.645913ms) +✔ AST extractor reads TypeScript and Python facts (381.756174ms) +✔ CLI command help is successful and non-mutating (1523.146341ms) +✔ TypeScript and Python CLIs execute the same intake command/query handler (1342.062899ms) +✔ CLI summarize exposes deterministic, prefer-llm and require-llm modes (2506.27039ms) +✔ CLI propose-todo, render-todo and apply-todo return JSON and preserve a no-op TODO (2105.457603ms) +✔ CLI watch reads TASK.md by default, disables summary LLM and reacts to a live file change (1802.02008ms) +✔ proposeCodeChangePlans materialises grounded plans from PLANNED_NOT_IMPLEMENTED (23.691785ms) +✔ code-change title preserves the leading action of a compound intent (3.156343ms) +✔ proposeCodeChangePlans is deterministic for the same evidence (3.174157ms) +✔ a plan creates a missing file and modifies an existing one (14.156334ms) +✔ a plan never invents a repository-root file from a bare filename (7.147562ms) +✔ a plan whose every path is bare and missing is withheld entirely (2.730263ms) +✔ a plan never targets a location outside the repository tree (0.257917ms) +✔ the repository probe never proposes creating a file outside the root (1.97475ms) +✔ bounded plan sets prefer explicit TODO work over historical changelog audit (4.030848ms) +✔ evaluateCodeChangeAcceptance passes when targeted diagnostics clear (6.798183ms) +✔ evaluateCodeChangeAcceptance fails while the plan is still open (2.846284ms) +✔ Plans without repository paths are not invented (0.971637ms) +✔ Non-repository paths are ignored instead of aborting code-change planning (1.312999ms) +✔ Acceptance rejects ungrounded paths, missing provenance and inconsistent verdicts (7.57769ms) +✔ createCodeChangeSourcePatch is deterministic and path-bound (8.224948ms) +✔ applyUnifiedDiffToText creates and modifies files from hunks (1.002069ms) +✔ applyCodeChangeSourcePatch requires approval and is idempotent (15.815665ms) +✔ applyCodeChangeSourcePatch preflights diffs and refuses symlink escapes (4.839585ms) +✔ createCodeChangeSourcePatchSet covers every plan (1.91563ms) +✔ createCodeChangeReviewPatch is hash-stable and lists grounded paths (2.371073ms) +✔ CLI proposes and evaluates a grounded code-change plan through persisted JSON (2253.4322ms) +✔ isUsefulCodeChangePath rejects vendored, binary and analysis dump paths (0.36542ms) +✔ proposeCodeChangePlans skips diagnostics that only name junk paths (1.545166ms) +✔ Published code-change JSON schemas require provenance, risk and rollback (5.211441ms) +✔ participant registry maps stable IDs to Git/A2A identifiers without display-name guessing (42.876126ms) +✔ participant registry rejects ambiguous external identifiers (0.58639ms) +✔ trusted intake persists roles across tickets and fails closed without rejected writes (77.528038ms) +✔ agents cannot create human projections and a damaged event hash fails verification (9.195871ms) +✔ TypeScript and dependency-free Python codecs share golden bytes and preserve unknown fields (295.511274ms) +✔ communication enrichment preserves runtime identity, source, ticket and epistemic class (58.315737ms) +✔ communication enrichment corrects one rejected structured response without weakening validation (30.419945ms) +✔ communication prefer-llm fallback is explicit and require-llm rejects (12.268839ms) +✔ project/ communication is attributed per human and agent and checked against Git evidence (305.78203ms) +✔ governance user-* and ai-* files become typed participant intent without ingesting ticket evidence (30.265956ms) +✔ unstructured governance participant content is rejected with an owner-specific migration warning (4.96289ms) +✔ opposite wording about different explicit files is not treated as an intent conflict (7.959577ms) +✔ missing response owners use explicit role sentinels without inventing participants (12.372879ms) +✔ communication extractor reports unresolved identity instead of inventing an actor (4.963592ms) +✔ communication extractor ignores generic generated analysis under project/ (9.190652ms) +✔ explicit OPENROUTER_APP_NAME overrides the project folder name (2.081787ms) +✔ missing or blank OPENROUTER_APP_NAME falls back to the resolved project folder (1.06824ms) +✔ OpenRouter application identity remains non-empty for a filesystem root (0.467962ms) +✔ configuration converter covers JSON, TOML, Docker and CI workflow declarations (60.627928ms) +✔ configuration converter emits a deterministic file aggregate for an empty configuration (7.167101ms) +✔ splitLines treats a trailing newline as a terminator, not an extra line (2.926891ms) +✔ Identical inputs produce no hunks (1.019712ms) +✔ A modified line keeps both sides addressable by original line number (0.740806ms) +✔ Pure insertion and pure deletion are not reported as replacements (1.156012ms) +✔ Empty-to-content and content-to-empty are handled as block changes (0.795698ms) +✔ Context width controls hunk size (0.545634ms) +✔ Nearby changes merge into a single hunk (0.427481ms) +✔ Distant changes stay in separate hunks (0.510264ms) +✔ Oversized inputs fall back to a bounded block replace (1.831769ms) +✔ Unified output carries a well formed hunk header (1.126553ms) +✔ Side-by-side rows pair deletions with insertions (0.630532ms) +✔ Unbalanced change runs leave one side empty rather than misaligning (1.379132ms) +✔ Renderers escape source markup (1.987506ms) +✔ SVG rendering caps rows and reports the remainder (6.100971ms) +✔ Reality view keys topics by target and records lane presence (37.999841ms) +✔ A topic holding declared and observed records is never reported as planned-only (7.146876ms) +✔ Reality coverage stays open when a shared path has unrelated capabilities (2.668309ms) +✔ Shared-path relations do not collapse unrelated files into one topic (4.172715ms) +✔ Reality view is deterministic for identical input (4.883979ms) +✔ Reality SVG escapes topic labels (2.457015ms) +✔ graph diff detects changed source identities, additions and SVG-safe labels (22.413375ms) +✔ graph diff is empty for graphs with identical evidence (2.182761ms) +✔ file diff emits deterministic unified, SVG and HTML views (2.161177ms) +✔ intent-vs-reality builds an explainable SVG and Markdown projection (4.570434ms) +✔ a targetless declaration is filed under the single module it links to (2.922085ms) +✔ a declaration touching several modules keeps its own topic (1.640992ms) +✔ a topic about a document does not absorb the statements written in it (1.9296ms) +✔ semantically aligned configuration topics retain their evidence grade (1.538053ms) +✔ A record claiming line 1 is re-anchored to the line carrying its statement (53.981152ms) +✔ An already correct line is kept and not reported as re-anchored (8.249486ms) +✔ An empty target is backfilled from the statement text (10.075178ms) +✔ A target supplied by the model is never overwritten (7.472562ms) +✔ An unclassified action and modality are derived from the statement (6.106937ms) +✔ A classified action from the model wins over the heuristic (7.604935ms) +✔ An action that stays unclassifiable is reported as a missing field (9.050695ms) +✔ A placeholder object is treated as a gap, not as content (9.230448ms) +✔ Every repair is attributable through epistemic.basis (7.659726ms) +✔ standalone source DSL facades preserve their canonical extractor results (91.171853ms) +✔ standalone source DSL facades reject invalid or foreign roots and files (2.915318ms) +✔ governed ticket README keeps wrapped goals and drops lifecycle metadata (12.051913ms) +✔ generic TASK.md line segmentation stays unchanged for headings (1.229743ms) +✔ deterministic documentation baseline records headings, code blocks and explicit references (22.115158ms) +✔ deterministic documentation preserves Polish prohibition polarity (8.528626ms) +✔ deterministic documentation resolves a unique bare filename against the repository (4.623928ms) +✔ documentation prose resolves a bare filename to its repository location (4.489624ms) +✔ a nested checkout does not shadow the repository copy of a documented file (7.411864ms) +✔ AST cache is incremental by path and source content hash (49.129319ms) +✔ AST cache rejects corrupt entries and recomputes authoritative records (14.971509ms) +✔ AST cache can be bypassed without changing extraction output (7.317527ms) +✔ successful external AST adapter is skipped on a warm manifest hit (310.11983ms) +✔ documentation chunks cache independently while provider calls remain live (44.707533ms) +✔ generated analysis replaces its source root with a stable token (77.938589ms) +✔ generated analysis root normalization refuses the filesystem root (76.789751ms) +✔ generated analysis rejects references to untracked input (120.477501ms) +✔ generated analysis accepts outputs independent of untracked input (115.14897ms) +✔ generated analysis accepts an untracked filename already quoted by tracked evidence (136.954847ms) +✔ generated analysis rejects temporary paths and unavailable validators (87.542402ms) +✔ generated README metadata is synchronized from package.json and stays idempotent (112.95676ms) +✔ generated README synchronization fails closed when the template drifts (57.106319ms) +✔ generated README synchronization rejects output outside the project root (55.958759ms) +✔ generated task and TODO projections are evidence unless communication explicitly opts in (57.222053ms) +✔ malformed front matter is rejected and non-ISO timestamps are reported (10.226486ms) +✔ assembles cited added, removed and modified truth changes (34.217591ms) +✔ keeps textual and semantic conflicts separate and cited (9.721829ms) +✔ unanchored cross-branch additions fail closed as unknown manual review (4.003033ms) +✔ duplicate changed source identities fail closed as unknown (4.444646ms) +✔ reuses one semantic bundle for refs sharing an exact tree (7.775569ms) +✔ rejects tampered Git materialization and mismatched semantic artifacts (2.549306ms) +✔ semantic bundle order and generated time do not alter portfolio identity (6.914986ms) +✔ materializes exact topology, conflicts, disjoint paths and equivalent patches read-only (584.017713ms) +✔ fingerprint is invariant to ref order and contains no clock metadata (466.846684ms) +✔ merge-tree result classifier fails closed on unavailable or ambiguous output (0.280488ms) +✔ rejects unsafe, duplicate, symbolic, missing and over-limit refs (185.957072ms) +✔ detects ref movement and removes temporary state after failure (217.240562ms) +✔ clean expected branch produces an exact deterministic PASS without changing Git state (577.383419ms) +✔ tracked, untracked and renamed paths are sorted and block a dirty workspace (301.85813ms) +✔ porcelain-v2 conflict facts and path bounds fail closed deterministically (6.47143ms) +✔ behind, detached and unexpected branches expose stable diagnostics and safe actions (686.389462ms) +✔ an ahead-only isolated branch remains usable but records a sync warning (297.351952ms) +✔ managed governance findings remain authoritative and unresolved scope blocks (336.556829ms) +✔ governance process failures keep their domain code and redact stderr (351.029484ms) +✔ implementation paths receive only the ticket selected by managed governance (309.291025ms) +✔ invalid roots, refs, checker output and options fail closed with stable codes (363.860838ms) +✔ report has no command, credential or absolute-root output and failure is read-only (320.87247ms) +✔ Git extractor emits one record per requested commit (274.719607ms) +✔ An empty repository degrades to a warning instead of failing the run (13.593765ms) +✔ versioned gold dataset reports perfect offline quality and repeated-run stability (174.625356ms) +✔ gold linking reports exact-target and capability-topic quality separately (67.586575ms) +✔ gold capability-topic support is large enough to detect a floor regression (63.846155ms) +✔ gold known gaps are measured and kept out of precision and recall (79.55433ms) +✔ gold reports cross-language positives and hard negatives as a separate cohort (95.254095ms) +✔ gold diagnostics separate a false DONE claim from an evidenced one (78.816096ms) +✔ gold v1 stays evaluable after the v2 contract extension (23.399786ms) +✔ gold loader rejects unsupported dataset versions (0.754844ms) +✔ gold evaluator rejects unknown linking cohorts (1.659518ms) +✔ gold v2 must declare diagnostics coverage (1.280885ms) +✔ published gold schema matches the runtime contract (2.669975ms) +✔ gold evaluator rejects fixture files outside its temporary workspace (7.69871ms) +✔ disjoint immutable candidates are bound to exact snapshots and merge-ready (16.970564ms) +✔ equivalent patch identity detects duplicate work across different commits (1.903996ms) +✔ textual and semantic conflicts stay separate and both block candidates (1.759559ms) +✔ contained or proven empty work is stale while unknown evidence requires review (0.966183ms) +✔ ordering and target movement produce merge-after and rebase recommendations (0.855724ms) +✔ ordering and generated time do not affect identity but a changed base does (2.613802ms) +✔ malformed identities and ungrounded semantic conflicts fail closed (0.675719ms) +✔ repository, counts, enums, digests and timestamps are validated strictly (0.6555ms) +✔ incomplete pair semantics cannot be classified as disjoint (0.63448ms) +✔ base semantic evidence and ordering citations survive projection (1.072877ms) +✔ ordering without related relation evidence fails closed (0.318974ms) +✔ missing, duplicate and self candidate pairs fail closed (0.555236ms) +✔ no unique work remains stale even when another branch has the same tree (0.731174ms) +✔ portfolio validation rejects tampering and authorization-like fields (0.880363ms) +✔ truth map groups explicit semantic evidence and preserves complete lineage (16.457192ms) +✔ structural relations do not collapse independent assertions (2.396044ms) +✔ explicit contradiction is visible and never selects a winner (0.983103ms) +✔ mixed claims remain distinct from factual support (0.966354ms) +✔ IDs and fingerprints are invariant to graph ordering and generatedAt (1.982429ms) +✔ invalid graph fingerprint and dangling relation endpoints fail closed (0.927029ms) +✔ truth map validator rejects duplicate assertion membership and reverse drift (1.138844ms) +✔ truth map validator rejects omitted mapping relations and artificial grouping (2.59374ms) +✔ Linker connects plan, Git claim and AST fact (20.363316ms) +✔ Linker connects prose intent to a module through three grounded capability topics (1.671635ms) +✔ Linker does not connect a module on one generic topic alone (1.249591ms) +✔ An existing target path does not prove an unrelated capability (2.629955ms) +✔ An existing target path plus an AST capability proves implementation (1.584447ms) +✔ Diagnostics distinguish descriptive documentation from prescriptive requirements (4.494172ms) +✔ A changelog entry naming an extracted documentation file has release evidence (1.908386ms) +✔ Diagnostics ignore non-actionable changelog mechanics but retain release claims (5.359782ms) +✔ Grounded conclusion and TODO proposal contracts accept traceable values (11.366845ms) +✔ Stable IDs ignore ordering noise but change with semantic content (1.015364ms) +✔ Validators reject ungrounded citations and stale semantic IDs (2.524603ms) +✔ Generation metadata exposes LLM failures instead of silently masking them (1.878046ms) +✔ TODO proposal collections enforce dependency integrity (1.237086ms) +✔ Published JSON schemas identify all grounded output contract versions (14.198771ms) +✔ Blank lines and comments produce no rules (1.455106ms) +✔ A pattern without a slash matches at any depth (0.453731ms) +✔ A leading slash anchors the pattern to the root (0.216592ms) +✔ A trailing slash restricts the rule to directories (0.200488ms) +✔ Wildcards respect path separators (0.41334ms) +✔ Every dot-directory is excluded by `.*/` (0.264743ms) +✔ Negation re-includes a previously excluded path (0.287121ms) +✔ Negation cannot resurrect a file inside an excluded directory (0.19639ms) +✔ Last matching rule wins (0.262346ms) +✔ Character classes are supported (0.33813ms) +✔ Paths are normalised before matching (0.196214ms) +✔ loadIgnoreMatcher merges the three ignore files and skips missing ones (12.892642ms) +✔ A repository without ignore files excludes nothing (0.905933ms) +✔ The shipped .intentignore excludes build output but keeps sources (2.479996ms) +✔ resolveGlobs permits one explicit .intent report without recursively scanning generated runs (6.928864ms) +✔ Two unrelated AST facts sharing only a file are not linked (13.236463ms) +✔ AST facts sharing a symbol are still linked despite the path rule (1.635175ms) +✔ AST details sharing only a file and generic tokens do not create a quadratic subgraph (3.715752ms) +✔ A file-level plan links once to the AST module aggregate instead of every detail (5.053234ms) +✔ A shared path still links a plan to an AST fact (0.974475ms) +✔ A bare filename links to a module only when its repository path is unique (1.631092ms) +✔ A bare filename refuses ambiguous module paths (1.393746ms) +✔ Relations that carry a conclusion survive alongside suppressed noise (1.734561ms) +✔ Pair ordering stays deterministic across rebuilds (1.685157ms) +✔ Two configuration declarations sharing only a key name are not linked (0.60355ms) +✔ A shared ticket still connects two configuration declarations (0.489376ms) +✔ Configuration still links to documentation that describes it (0.399581ms) +✔ Configuration file aggregate is the file-level target for an explicit documentation path (0.548041ms) +✔ Configuration aggregates do not create broad capability-topic links (0.361737ms) +✔ a full six-stage live run passes and reports every stage (3.540981ms) +✔ a stage that silently fell back to deterministic fails the check (0.49104ms) +✔ a missing stage cannot pass as covered (0.323058ms) +✔ per-stage and total budgets are enforced separately (0.516151ms) +✔ live request timeout reaches the stage budget without shortening a larger override (0.234127ms) +✔ a stage reason is recorded with provider text redacted (0.900434ms) +✔ history records the trend without gating on it (0.495964ms) +✔ recorded audit history includes the current run exactly once (0.562277ms) +✔ history stays chronological, bounded and free of duplicate runs (9.936775ms) +✔ an audit converts to exactly the redacted fields history keeps (0.550998ms) +✔ an empty history summarizes without pretending to have measured anything (0.283388ms) +✔ a batched run is measured per record, not per request (5.844807ms) +✔ a model whose response the validator rejected is not counted as enriched (0.493562ms) +✔ a failed model is a comparison result rather than a crash (1.185821ms) +✔ agreement compares only records both models enriched (0.507206ms) +✔ agreement is absent rather than perfect when nothing overlaps (0.747662ms) +✔ the rendered comparison names the cheapest and fastest passing model (0.438536ms) +✔ semantic LLM modes default to require-llm (1.74138ms) +✔ Markdown extractor separates TODO plans and changelog claims (19.041104ms) +✔ Markdown extractor preserves indented continuation lines and their source range (7.187908ms) +✔ TODO bare filenames inherit an existing directory from the heading scope (2.698367ms) +✔ TODO resolves a bare filename only when its repository basename is unique (2.592381ms) +✔ TODO and CHANGELOG resolve the same bare filename to one repository path (2.617989ms) +✔ CHANGELOG keeps an ambiguous bare filename unresolved (1.689616ms) +✔ Markdown path resolution drops paths and heading scopes outside the repository (1.065703ms) +✔ TODO and CHANGELOG receive audited LLM enrichment without changing structural facts (29.584348ms) +✔ Markdown enrichment corrects one rejected response and audits both attempts (4.495019ms) +✔ large Markdown enrichment uses bounded concurrency and keeps provider audits ordered (53.24521ms) +✔ TODO and CHANGELOG LLM fallback and require mode are explicit (3.817647ms) +✔ TODO and CHANGELOG reject structurally invalid LLM enrichments (4.137766ms) +✔ a truncated batch is split and every record keeps its own response provenance (5.370133ms) +✔ a malformed batch response splits instead of failing the whole stage (6.77716ms) +✔ MCP 2026 profile is stateless and exposes discovery plus complete results (4.755343ms) +✔ MCP 2026 rejects missing metadata and unsupported versions with protocol errors (1.045446ms) +✔ MCP legacy profile negotiates 2025-11-25 and requires initialize (0.615981ms) +✔ MCP exposes annotated intake command/query tools backed by the domain handler (18.587961ms) +✔ An LLM record is marked as inference and keeps runtime-owned provenance (34.583175ms) +✔ NL extraction corrects one rejected structured response and audits both attempts (4.359484ms) +✔ Confidence must satisfy the provider schema instead of being silently clamped (10.675133ms) +✔ Source lines are clamped to the real file (2.40136ms) +✔ A placeholder object is recorded as a missing field, not as content (14.326167ms) +✔ A real object is kept verbatim and reports no missing field (1.554175ms) +✔ The explicit unknown action is reported as a missing field (2.174852ms) +✔ Both gaps are reported together (2.045484ms) +✔ Out-of-vocabulary enums are rejected instead of changing the provider intent (4.801852ms) +✔ Rejected NL output keeps provider metadata in the failed audit (3.644482ms) +✔ The documented confidence hierarchy holds across LLM extractors (1.424473ms) +✔ NL extractor produces deterministic non-LLM records (9.65189ms) +✔ NL public extraction boundary names a missing sourcePath before path resolution (0.928901ms) +✔ deterministic NL fallback skips Markdown headings and recognizes comparison intent (2.183972ms) +✔ path extraction rejects lowercase prose alternations without losing repository paths (0.979678ms) +✔ path extraction rejects dotted DSL fields but keeps known file extensions (0.237683ms) +✔ detectModality ignores parenthetical labels and bare adjectives (0.440999ms) +✔ detectModality reads prohibitions and periphrastic obligation as requirements (0.555026ms) +✔ detectPolarity does not treat without-complements as sentence negation (0.192841ms) +✔ path extraction rejects HTTP routes, host paths and parent traversal (0.277205ms) +✔ symbol extraction rejects hostnames without losing qualified code symbols (0.387512ms) +✔ symbol extraction separates repository files and all-caps prose from code identifiers (0.226454ms) +✔ topic keywords normalize paths, camelCase and documentation word forms (0.449734ms) +✔ NL LLM extraction emits audited provenance and bounded DSL records (38.098986ms) +✔ NL LLM failure is explicit when deterministic fallback is used (5.991766ms) +✔ require-llm rejects instead of silently falling back (0.643119ms) +✔ adaptive OpenRouter timeout scales at exact power-of-two boundaries (1.020309ms) +✔ output budget and structural complexity independently scale timeout (0.34908ms) +✔ adaptive OpenRouter timeout caps at ten minutes (1.01851ms) +✔ adaptive OpenRouter timeout rejects malformed and unbounded inputs (0.550903ms) +✔ OpenRouter audit records the non-secret adaptive timeout policy (1.078182ms) +✔ external cancellation remains immediate before an OpenRouter fetch (0.947943ms) +✔ retry backoff remains inside one effective OpenRouter deadline (31.683985ms) +✔ OpenRouter client parses structured JSON without exposing key (26.599687ms) +✔ OpenRouter client preserves metadata when runtime rejects structured output (1.757474ms) +✔ OpenRouter client lists available models after an invalid model ID (12.284776ms) +✔ OpenRouter client redacts provider key-management evidence while retaining the failure reason (3.457551ms) +✔ OpenRouter model-list failures redact credentials and contextual credential identifiers (1.134511ms) +✔ OpenRouter JSON timeout is not repeated as a schema fallback request (0.905014ms) +✔ OpenRouter request obeys a shared pipeline deadline without retrying (0.964552ms) +✔ Documentation extractor converts OpenRouter structured output to bounded LLM records (17.75846ms) +✔ Documentation extractor reports and enforces its chunk budget (3.953608ms) +✔ Documentation extractor corrects one rejected chunk and audits both responses (4.350082ms) +✔ Documentation extractor does not spend its correction retry on a timeout (4.519224ms) +✔ Documentation extractor exposes an audited configuration failure (0.530408ms) +✔ Documentation extractor uses bounded concurrent OpenRouter requests (37.884826ms) +✔ LLM summarizer receives graph data and preserves grounded record citations (11.646333ms) +✔ LLM summarizer validates provider fields before creating semantic IDs (5.663672ms) +✔ LLM summarizer diagnoses a provider that ignores the response envelope (2.904987ms) +✔ LLM summarizer rejects diagnostic citations outside the supplied graph (5.902589ms) +✔ LLM summarizer prioritizes documentation over the AST payload budget (195.851442ms) +✔ deterministic summary presents AST module aggregates instead of low-level calls (4.07487ms) +✔ The summarizer grounds a fabricated record citation from its diagnostic (5.656184ms) +✔ The summarizer still fails when the retry fabricates a diagnostic again (3.947783ms) +✔ variable contracts and operation plans have deterministic content-bound IDs (5.198184ms) +✔ every variable grants Founder read/write authority and immutable variables reject other writers (0.711172ms) +✔ plans reject undeclared parameters, actor visibility gaps and payload secrets (1.179764ms) +✔ safety-sensitive commands require a Founder decision, a human boundary and verification (0.906548ms) +✔ plan hash detects semantic tampering (1.060705ms) +✔ compiler emits the exact governed envelope without an execution surface (1.139736ms) +✔ runtime draft boundaries ignore lifecycle and identity fields injected by untyped callers (0.538666ms) +✔ compiler fails closed on extra, stale, wrong-source and wrong-type bindings (1.38448ms) +✔ file boundary writes one private envelope atomically and refuses overwrite (13.712534ms) +✔ canonical ticket-045 fixture parses and renders byte-for-byte (19.369696ms) +✔ identical semantic inputs render identically and sort by canonical recording order (1.097794ms) +✔ parser fails closed on tampered chains and non-canonical encoding (0.936942ms) +✔ unsafe evidence, secrets and advisory approval are rejected before rendering (0.459603ms) +✔ writer publishes one validated file atomically and refuses an immutable overwrite (7.20944ms) +✔ Offline pipeline writes a complete run (274.480474ms) +✔ Pipeline writes a canonical event log for a successful deterministic run (36.089349ms) +✔ Pipeline persists synthesis, validation and review patch, then registers approval receipt (82.115045ms) +✔ Pipeline integrates multi-participant communication into graph, diagnostics, reality and run artifacts (76.684819ms) +✔ Pipeline require-llm task synthesis failure is audited and never publishes latest (50.632697ms) +✔ Pipeline persists an audited failure when communication require-llm cannot run (38.712841ms) +✔ Pipeline persists communication stage failure and does not publish latest (28.203759ms) +✔ Pipeline persists a failed manifest when NL require-llm aborts (17.816638ms) +✔ Pipeline persists a failed manifest when Markdown require-llm aborts (28.01989ms) +✔ Pipeline persists a failed manifest for an unexpected summary failure (33.080992ms) +✔ descriptive update intents do not create missing nested paths (35.763339ms) +✔ Proposal validation reports existing TODO duplicates and orders dependencies before priority (22.975096ms) +✔ Proposal validation rejects dependency cycles and whitespace-only criterion duplicates (3.12098ms) +✔ Python package executes the local TypeScript reality runtime without a server (1870.722281ms) +✔ runtime cycle extractor turns probes, violations, drift and proposals into records (30.092312ms) +✔ measurements enter as fact and the cycle own suggestions as inference (3.79776ms) +✔ a violated expectation is negative and blocked, a healthy probe positive and verified (3.294634ms) +✔ a probe that could not run is unknown, not failing (2.793345ms) +✔ a watched path lets a runtime fact link to the code that produces it (25.768873ms) +✔ a document that is not an autonom cycle is refused by schema, not silently empty (2.774868ms) +✔ Runtime validator enforces the complete Intent DSL enum and object contract (5.084049ms) +✔ Linker and remote action boundary reject malformed records before graph construction (10.085939ms) +✔ Graph validator rejects invalid relations and inconsistent statistics (3.627743ms) +[t2c:a2a] listening on 127.0.0.1:39271 +✔ diff UI and TypeScript/Python SDKs use the live backend runtime (431.673376ms) +✔ MCP/A2A action boundary rejects traversal and symlink escapes (53.035816ms) +✔ bounded retrieval cannot create a relation until a grounded reranker accepts it (28.802226ms) +✔ reranker fails closed on ungrounded quotes and more than one accepted module (5.295238ms) +✔ OpenRouter reranking is required, structured and reusable only through an identity-bound cache (121.25266ms) +✔ published semantic reranker schemas expose the versioned bounded contracts (2.456804ms) +✔ provider response validation diagnoses the exact property without coercion (0.643064ms) +✔ analysis policy renders and parses one canonical byte representation (5.111831ms) +✔ deterministic triggers select required LLM stages and exact usage ceilings (0.675561ms) +✔ selection rejects unknown, duplicate and non-canonical trigger input (0.895214ms) +✔ policy and exact-evidence cache fingerprints bind every semantic input (4.047419ms) +✔ token ceilings convert to a deterministic provider-rate cost bound (0.664102ms) +✔ policy rejects semantic fallback and non-exact cache modes (0.48626ms) +✔ stage topology and nested budgets fail closed (1.492735ms) +✔ parser rejects non-canonical and structurally ambiguous text (0.817015ms) +✔ one structured contract emits the provider schema and parses the same value (1.880674ms) +✔ structured parsing fails closed with the exact response path (2.079906ms) +✔ object uniqueness uses canonical JSON identity rather than property order (0.368013ms) +✔ SubLLM bridge resolves the selected central route without command-shell interpolation (453.76358ms) +✔ todo2code sends structured semantic requests through direct Z.AI resolved by SubLLM (381.724332ms) +✔ explicitly requested SubLLM fails closed when its package is unavailable (2.941114ms) +✔ a short NL symbol resolves to its only AST owner (19.361849ms) +✔ an ambiguous short NL symbol does not pretend that either AST owner is selected (4.070324ms) +✔ an explicit path selects one owner of an otherwise ambiguous symbol (2.143314ms) +✔ a qualified symbol selects its exact AST declaration without a path (1.606418ms) +✔ a symbol and explicit path conflict reports the observed AST location (2.388439ms) +✔ missingFields diagnostics prescribe a concrete edit for every known gap (0.847955ms) +✔ Target normalization canonicalizes paths, symbols and cross-language separators (2.188957ms) +✔ Qualified AST symbols align with short plan and documentation targets (23.780641ms) +✔ Structured task synthesis materializes stable, grounded contracts with a complete audit (59.028675ms) +✔ blank response-local proposal keys are rejected instead of invented by the runtime (10.315838ms) +✔ prefer-llm exposes raw diagnostic actions without claiming semantic task generation (2.164347ms) +✔ communication divergence is grounded in task synthesis without treating agent claims as facts (8.116504ms) +✔ task synthesis defaults to require-llm and fails explicitly without a provider (1.036084ms) +✔ invalid structured LLM citations are rejected or visibly degraded according to mode (11.412781ms) +✔ task synthesis timeout is audited and never retried as a format fallback (16.549064ms) +✔ A fabricated record citation is grounded from its cited diagnostic without a retry (4.505068ms) +✔ A fabricated diagnostic still fails after the corrective retry (5.368724ms) +✔ TensorFlow remains an explicit fallback when the isolated adapter is not installed (4.905375ms) +✔ TODO patch rendering is stable, dependency-first and excludes classified duplicates (19.961376ms) +✔ empty and duplicate-only results render an explicit no-op patch (2.186522ms) +✔ apply rejects missing or wrong approval, stale TODO and a tampered patch (14.671806ms) +✔ approved apply is atomic, receipt-backed and idempotent (12.308456ms) +✔ service actions execute LLM propose -> render -> approved apply with scoped artifacts (52.456042ms) +✔ scanTree prunes ignored directories and records file signatures (20.098805ms) +✔ diffSnapshots classifies additions, modifications and removals (0.47869ms) +✔ describeDelta truncates long change lists (0.180122ms) +✔ An unchanged tree produces exactly one report and then stays quiet (5.215879ms) +✔ Reports are rate limited to one per interval no matter how often files change (39.352842ms) +✔ A change is reported once the interval has elapsed (8.441661ms) +✔ Ignored files never trigger a report (4.642585ms) +✔ A failing report is surfaced and does not stop the watcher (2.138893ms) +✔ --no-initial-report waits for a real change (1.803981ms) +✔ Communication changes trigger watch and coalesce under the existing report rate limit (7.456392ms) +✔ workflow verifier rejects duplicate top-level YAML keys (101.01254ms) +✔ workspace preflight help and required input fail before repository inspection (118.621819ms) +✔ workspace preflight maps canonical PASS and BLOCKED reports without Git mutation (610.285228ms) +✔ Make quotes caller input as one argument in its preflight recipe (3.263572ms) +✔ Make preflight reserves stdout for one canonical report (5833.983613ms) +✔ GitHub event collector maps supported push payloads to canonical event logs (69.234351ms) +✔ GitHub review events are SYSTEM_FACT and cannot become approval attestation (42.340239ms) +✔ GitHub review with unsupported state fails closed (41.718167ms) +✔ Evidence projection is allowlisted and extra payload fields do not leak into logs (88.901136ms) +✔ GitHub acquisition ignores ambient environment and requires explicit input (127.970468ms) +✔ workspace comparison deadline scales aggregate input and LLM work in bounded 2x steps (1.197764ms) +✔ workspace headline trend ignores AST-only topic and source churn (0.243549ms) +✔ workspace comparison measures origin/main against uncommitted filesystem intent (447.551287ms) +ℹ tests 425 +ℹ suites 0 +ℹ pass 424 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 1 +ℹ todo 0 +ℹ duration_ms 17065.050738 +GOV-PASS: passed (0 errors, 0 warnings) diff --git a/project/ticket-082/ai-gpt-5.6-sol.md b/project/ticket-082/ai-gpt-5.6-sol.md new file mode 100644 index 0000000..3e54c10 --- /dev/null +++ b/project/ticket-082/ai-gpt-5.6-sol.md @@ -0,0 +1,9 @@ +--- +participant-id: agent:gpt-5.6-sol +participant: gpt-5.6-sol +role: agent +ticket: ticket-082 +--- +# Participant: gpt-5.6-sol + +Set `T2C_VERSION` to `0.5.1`. diff --git a/project/ticket-082/changelog.md b/project/ticket-082/changelog.md new file mode 100644 index 0000000..0b00aa3 --- /dev/null +++ b/project/ticket-082/changelog.md @@ -0,0 +1,5 @@ +# Ticket Changelog (ticket-082) + +## [0.1.0] - 2026-08-17 + +- Aligned `T2C_VERSION` with package version `0.5.1`. diff --git a/project/ticket-082/intent.json b/project/ticket-082/intent.json new file mode 100644 index 0000000..30a5768 --- /dev/null +++ b/project/ticket-082/intent.json @@ -0,0 +1,62 @@ +{ + "schema": "new-project.intent/v3", + "ticket": "ticket-082", + "summary": "Align T2C_VERSION with package 0.5.1", + "workstream": "core-dsl", + "classification": { + "kind": "BUG", + "priority": "P1", + "origin": "regression" + }, + "allowedPaths": [ + "project/ticket-082/**", + "TODO.md", + "project/TICKETS.md", + "src/core/version.ts" + ], + "forbiddenPaths": [ + "project/ticket-*/user-*.md", + "test/**" + ], + "stacks": ["node"], + "dependsOn": ["ticket-080", "ticket-081"], + "conflictsWith": [], + "integrationTicket": null, + "delivery": { + "acceptedBaseSha": "6acd6a505c5b521effb5724a6eb28be283106626", + "targetBranch": "main", + "outcome": "Generated provenance reports runtime version 0.5.1 matching package.json.", + "nonGoals": ["No package.json change", "No historical fixture rewrites"], + "complexity": "XS", + "estimatedMinutes": 8, + "budgets": { + "maxImplementationFiles": 1, + "maxAffectedComponents": 1, + "maxPublicInterfaceChanges": 0, + "maxRuntimeDependencies": 0 + }, + "architecture": { + "status": "accepted", + "decision": "Set T2C_VERSION to 0.5.1 after dependent workstreams bound assertions to the shared constant.", + "components": [ + { + "name": "runtime-version-constant", + "paths": ["src/core/version.ts"] + } + ], + "responsibilityChanges": false, + "interfaceChanges": [], + "dataChanges": [], + "ui": {"impact": "none", "states": [], "evidence": []}, + "rollback": "Restore T2C_VERSION 0.5.0." + }, + "runtimeDependencies": [], + "validation": [ + { + "criterion": "AC-01", + "commands": ["npm run build", "npm test"], + "evidence": "project/ticket-082/ai-gpt-5.6-sol-logs.txt" + } + ] + } +} diff --git a/project/ticket-082/preprompt.md b/project/ticket-082/preprompt.md new file mode 100644 index 0000000..28d9581 --- /dev/null +++ b/project/ticket-082/preprompt.md @@ -0,0 +1,8 @@ +# Ticket preprompt + +- **Task ID**: ticket-082 +- **Task title**: Align T2C_VERSION with package 0.5.1 +- **Created**: 2026-08-17T11:14:57Z + +Keep executable implementation outside this governance/evidence directory. +Read a human-owned user-*.md file only when one exists. diff --git a/src/core/version.ts b/src/core/version.ts index 123e2b7..a8d5e3c 100644 --- a/src/core/version.ts +++ b/src/core/version.ts @@ -1,2 +1,2 @@ /** Runtime version embedded in every generated DSL provenance envelope. */ -export const T2C_VERSION = '0.5.0'; +export const T2C_VERSION = '0.5.1'; diff --git a/src/extractors/nl.ts b/src/extractors/nl.ts index ef9d8e7..73ec692 100644 --- a/src/extractors/nl.ts +++ b/src/extractors/nl.ts @@ -12,7 +12,7 @@ import { inferObject, splitIntentLines, } from '../core/text.js'; -import type { ExtractionResult, IntentRecord } from '../core/types.js'; +import type { ExtractionResult, IntentAction, IntentRecord } from '../core/types.js'; import { classifyAction } from '../tf/classifier.js'; export interface NlExtractionOptions { @@ -44,12 +44,15 @@ export async function extractNlIntent(options: NlExtractionOptions, config: T2CC : options.sourcePath.replace(/\\/g, '/'); const records: IntentRecord[] = []; const warnings: string[] = []; + const segments: IntentSegment[] = isGovernedTicketReadme(sourcePath) + ? segmentGovernedTicketReadme(body) + : splitIntentLines(body).map((segment) => ({ ...segment, kind: 'generic' as const })); - for (const segment of splitIntentLines(body)) { + for (const segment of segments) { const classified = await classifyAction(segment.text, config); - const action = classified.action; + const action = refineTicketSegmentAction(segment, classified.action); const object = inferObject(segment.text, action); - const missing = detectMissingFields(segment.text, action, object); + const missing = detectMissingFields(segment.text, action, object, segment.kind); const confidence = Math.max(0.35, classified.confidence - missing.length * 0.06); records.push(buildRecord({ kind: 'declared_intent', @@ -68,14 +71,22 @@ export async function extractNlIntent(options: NlExtractionOptions, config: T2CC lifecycle: 'proposed', sourceKind: 'nl', sourcePath, - sourceLines: { start: segment.line, end: segment.line }, - extractor: 't2c/nl-heuristic@1', + sourceLines: { start: segment.line, end: segment.endLine ?? segment.line }, + extractor: segment.kind === 'generic' + ? 't2c/nl-heuristic@1' + : 't2c/nl-ticket-readme@1', epistemicClass: 'declaration', confidence, - basis: [classified.basis, 'line_segmentation', 'modality_dictionary', 'target_heuristics'], + basis: [ + classified.basis, + segment.kind === 'generic' ? 'line_segmentation' : 'ticket_section_segmentation', + 'modality_dictionary', + 'target_heuristics', + ], metadata: { missingFields: missing, llmUsed: false, + ...(segment.kind !== 'generic' ? { ticketSegment: segment.kind } : {}), }, })); } @@ -84,6 +95,214 @@ export async function extractNlIntent(options: NlExtractionOptions, config: T2CC return { records, warnings }; } +type TicketSegmentKind = 'goal' | 'acceptance' | 'generic'; + +interface IntentSegment { + text: string; + line: number; + endLine?: number; + kind: TicketSegmentKind; +} + +const TICKET_README_PATH = /(^|\/)project\/ticket-\d+\/README\.md$/i; +const METADATA_LABEL = /^\*\*(?:ID|Owner|Status|Workflow state|Created)\*\*\s*:/i; +const GOAL_SECTION = /^(?:Goal(?:\s+and\s+scope)?|Cel(?:\s+i\s+zakres)?)\b/i; +const ACCEPTANCE_SECTION = /^(?:Acceptance criteria|Kryteria akceptacji)\b/i; + +/** True when the source is a governed new-project ticket README. */ +export function isGovernedTicketReadme(sourcePath: string): boolean { + return TICKET_README_PATH.test(sourcePath.replace(/\\/g, '/')); +} + +/** + * Segment a governed ticket README by semantic sections. + * + * Lifecycle metadata (`Status`, `Owner`, …) is dropped. Wrapped goal and + * acceptance-criterion lines stay as single records with the originating + * source line range. + */ +export function segmentGovernedTicketReadme(text: string): IntentSegment[] { + const lines = text.split(/\r?\n/); + const output: IntentSegment[] = []; + let section: 'meta' | 'goal' | 'acceptance' | 'skip' = 'meta'; + let goalBuffer: string[] = []; + let goalStart = 0; + let goalEnd = 0; + let acceptanceBuffer: string[] = []; + let acceptanceStart = 0; + let acceptanceEnd = 0; + + const flushGoal = (): void => { + const value = goalBuffer.join(' ').replace(/\s+/g, ' ').trim(); + if (value.length >= 3) { + output.push({ text: value, line: goalStart, endLine: goalEnd, kind: 'goal' }); + } + goalBuffer = []; + }; + + const flushAcceptance = (): void => { + const value = acceptanceBuffer.join(' ').replace(/\s+/g, ' ').trim(); + if (value.length >= 3) { + output.push({ + text: value, + line: acceptanceStart, + endLine: acceptanceEnd, + kind: 'acceptance', + }); + } + acceptanceBuffer = []; + }; + + for (let index = 0; index < lines.length; index += 1) { + const raw = lines[index] ?? ''; + const heading = raw.match(/^\s{0,3}#{1,6}\s+(.*)$/); + if (heading) { + flushGoal(); + flushAcceptance(); + section = sectionForHeadingTitle((heading[1] ?? '').trim()); + continue; + } + + if (section === 'meta' || section === 'skip') { + continue; + } + + const cleaned = stripListMarker(raw); + if (section === 'goal') { + ({ goalBuffer, goalStart, goalEnd } = absorbProseLine({ + cleaned, + buffer: goalBuffer, + start: goalStart, + end: goalEnd, + lineNumber: index + 1, + onBlank: flushGoal, + skip: () => METADATA_LABEL.test(cleaned), + })); + continue; + } + + ({ + acceptanceBuffer, + acceptanceStart, + acceptanceEnd, + } = absorbAcceptanceLine({ + raw, + cleaned, + buffer: acceptanceBuffer, + start: acceptanceStart, + end: acceptanceEnd, + lineNumber: index + 1, + onBlankOrBoundary: flushAcceptance, + })); + } + + flushGoal(); + flushAcceptance(); + return output; +} + +function sectionForHeadingTitle(title: string): 'goal' | 'acceptance' | 'skip' { + if (GOAL_SECTION.test(title)) return 'goal'; + if (ACCEPTANCE_SECTION.test(title)) return 'acceptance'; + return 'skip'; +} + +function stripListMarker(raw: string): string { + return raw + .replace(/^\s*[-*+]\s+/, '') + .replace(/^\s*\d+[.)]\s+/, '') + .replace(/^\s*\[[ xX]\]\s+/, '') + .trim(); +} + +function absorbProseLine(input: { + cleaned: string; + buffer: string[]; + start: number; + end: number; + lineNumber: number; + onBlank: () => void; + skip: () => boolean; +}): { goalBuffer: string[]; goalStart: number; goalEnd: number } { + if (!input.cleaned) { + input.onBlank(); + return { goalBuffer: [], goalStart: input.start, goalEnd: input.end }; + } + if (input.skip()) { + return { goalBuffer: input.buffer, goalStart: input.start, goalEnd: input.end }; + } + if (input.buffer.length === 0) { + return { + goalBuffer: [input.cleaned], + goalStart: input.lineNumber, + goalEnd: input.lineNumber, + }; + } + return { + goalBuffer: [...input.buffer, input.cleaned], + goalStart: input.start, + goalEnd: input.lineNumber, + }; +} + +function absorbAcceptanceLine(input: { + raw: string; + cleaned: string; + buffer: string[]; + start: number; + end: number; + lineNumber: number; + onBlankOrBoundary: () => void; +}): { acceptanceBuffer: string[]; acceptanceStart: number; acceptanceEnd: number } { + const isCheckbox = /^\s*[-*+]\s+\[[ xX]?\]\s+/.test(input.raw) || /^\s*[-*+]\s+AC-\d+/i.test(input.raw); + const isContinuation = !isCheckbox && /^\s{2,}\S/.test(input.raw); + + if (isCheckbox) { + input.onBlankOrBoundary(); + if (!input.cleaned) { + return { acceptanceBuffer: [], acceptanceStart: input.start, acceptanceEnd: input.end }; + } + return { + acceptanceBuffer: [input.cleaned], + acceptanceStart: input.lineNumber, + acceptanceEnd: input.lineNumber, + }; + } + + if (isContinuation && input.buffer.length) { + if (!input.cleaned) { + return { acceptanceBuffer: input.buffer, acceptanceStart: input.start, acceptanceEnd: input.end }; + } + return { + acceptanceBuffer: [...input.buffer, input.cleaned], + acceptanceStart: input.start, + acceptanceEnd: input.lineNumber, + }; + } + + if (!input.cleaned) { + input.onBlankOrBoundary(); + return { acceptanceBuffer: [], acceptanceStart: input.start, acceptanceEnd: input.end }; + } + + // Non-checkbox prose under Acceptance criteria still counts as a criterion. + input.onBlankOrBoundary(); + return { + acceptanceBuffer: [input.cleaned], + acceptanceStart: input.lineNumber, + acceptanceEnd: input.lineNumber, + }; +} + +function refineTicketSegmentAction( + segment: IntentSegment, + classified: IntentAction, +): IntentAction { + if (segment.kind === 'acceptance') return 'validate'; + if (segment.kind === 'goal' && classified === 'unknown') return 'change'; + return classified; +} + function inferActor(text: string): string | null { if (/\b(agent|stażysta|intern)\b/i.test(text)) return 'agent'; if (/\b(system|aplikacja|runtime)\b/i.test(text)) return 'system'; @@ -92,7 +311,12 @@ function inferActor(text: string): string | null { return null; } -function detectMissingFields(text: string, action: string, object: string): string[] { +function detectMissingFields( + text: string, + action: string, + object: string, + kind: TicketSegmentKind = 'generic', +): string[] { const missing: string[] = []; if (action === 'unknown') missing.push('action'); if (!object || object === 'unspecified' || object.length < 3) missing.push('object'); @@ -100,6 +324,9 @@ function detectMissingFields(text: string, action: string, object: string): stri if (!/\b(before|after|when|on|przed|po|gdy|kiedy|podczas)\b/i.test(text)) missing.push('trigger'); if (!/\b(error|fail|reject|return|błąd|odrzuc|zwr[oó]ć)\b/i.test(text)) missing.push('failure_behavior'); } + if (kind === 'acceptance' || /\bAC-\d+\b/i.test(text)) { + return [...new Set(missing.filter((item) => item !== 'acceptance_evidence' && item !== 'action'))].sort(); + } if (!/\b(test|acceptance|kryteri|dow[oó]d|evidence|result|wynik)\b/i.test(text) && text.length < 45) { missing.push('acceptance_evidence'); } diff --git a/src/synthesis/code-change-plan-propose.ts b/src/synthesis/code-change-plan-propose.ts index 7548551..22ffa6b 100644 --- a/src/synthesis/code-change-plan-propose.ts +++ b/src/synthesis/code-change-plan-propose.ts @@ -214,13 +214,17 @@ function buildChanges( const rationale = sourceIntents.length ? `Implement the source intent: ${sourceIntents.join(' | ')}` : diagnostic.detail || `Address ${diagnostic.code}.`; + const mayCreate = hasExplicitCreateIntent(records); if (target.paths.length) { const changes: CodeChangeFile[] = []; for (const declared of uniqueSorted(target.paths)) { const normalized = declared.replace(/\\/g, '/'); const exists = pathExistsInRepository?.(normalized); + // Bare missing filenames are ambiguous (often prose fragments). if (exists === false && !normalized.includes('/')) continue; + // Missing nested paths need an explicit add/create/implement intent. + if (exists === false && !mayCreate) continue; const action: CodeChangeFileAction = exists === false ? 'create' : 'modify'; changes.push({ path: normalized, action, symbols, rationale }); } @@ -230,6 +234,15 @@ function buildChanges( return []; } +/** True when source intents explicitly ask to add or create something. */ +function hasExplicitCreateIntent(records: IntentRecord[]): boolean { + const createVerb = /\b(add|create|implement|introduce|build|utworzy(?:ć|c)|doda(?:ć|c)|zaimplementowa(?:ć|c)|stworzy(?:ć|c)|zbudowa(?:ć|c))\b/i; + return records.some((record) => { + if (record.statement.action === 'add') return true; + return createVerb.test(record.statement.text); + }); +} + function titleFor(diagnostic: Diagnostic, records: IntentRecord[]): string { const record = records[0]; const object = record?.statement.object?.trim(); diff --git a/test/code-change-plan.test.ts b/test/code-change-plan.test.ts index 67471ae..f4bb593 100644 --- a/test/code-change-plan.test.ts +++ b/test/code-change-plan.test.ts @@ -475,7 +475,7 @@ test('createCodeChangeSourcePatch is deterministic and path-bound', () => { assert.throws(() => createCodeChangeSourcePatch({ plan, unifiedDiffs: { - 'src/contracts.ts': '--- a/src/contracts.ts\n+++ b/src/contracts.ts\n@@ -0,0 +1 @@\n+api_key = "supersecretvalue"\n', + 'src/contracts.ts': '--- a/src/contracts.ts\n+++ b/src/contracts.ts\n@@ -0,0 +1 @@\n+password = "xxx-blocked-by-runtime"\n', }, }), /secret assignment/); @@ -730,7 +730,7 @@ test('CLI proposes and evaluates a grounded code-change plan through persisted J assert.equal(closeResult.acceptedCount, 1); assert.equal(closeResult.allAccepted, true); assert.equal(closeResult.generation.generator, 't2c/code-change-close-result'); - assert.equal(closeResult.generation.runtimeVersion, '0.5.0'); + assert.equal(closeResult.generation.runtimeVersion, T2C_VERSION); assert.equal(closeResult.generation.model, null); }); diff --git a/test/docs-ticket-readme.test.ts b/test/docs-ticket-readme.test.ts new file mode 100644 index 0000000..8889d79 --- /dev/null +++ b/test/docs-ticket-readme.test.ts @@ -0,0 +1,77 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { extractNlIntent } from '../src/extractors/nl.js'; +import { makeConfig } from './helpers.js'; + +const GOVERNED_TICKET_README = [ + '# Ticket 079: Organization identity and management', + '', + '- **ID**: ticket-079', + '- **Owner**: unresolved:human', + '- **Status**: DONE', + '- **Workflow state**: DONE', + '- **Created**: 2026-03-20', + '', + '## Goal and scope', + '', + 'Add clickable organization management in the account panel so operators can', + 'list, switch, and create organizations without leaving the portal.', + '', + '## Acceptance criteria', + '', + '- [ ] AC-01: Organizacje rail opens the organization tab and shows the', + ' membership list from the session.', + '- [ ] AC-02: Creating an organization rotates the session cookie.', + '', + '## Participants', + '', + '- Human participant: unresolved.', + '', +].join('\n'); + +test('governed ticket README keeps wrapped goals and drops lifecycle metadata', async () => { + const config = makeConfig(process.cwd()); + const result = await extractNlIntent({ + root: process.cwd(), + sourcePath: 'project/ticket-079/README.md', + text: GOVERNED_TICKET_README, + }, config); + + assert.equal(result.records.length, 3); + assert.ok(!result.records.some((record) => /\bStatus\b|\bOwner\b|\bWorkflow state\b/i.test(record.statement.text))); + assert.equal(result.records[0]?.statement.action, 'add'); + assert.match(result.records[0]?.statement.text ?? '', /list, switch, and create organizations/); + assert.deepEqual(result.records[0]?.source.lines, { start: 11, end: 12 }); + assert.equal(result.records[0]?.source.extractor, 't2c/nl-ticket-readme@1'); +}); + +test('governed ticket README maps acceptance criteria to validate intents', async () => { + const config = makeConfig(process.cwd()); + const result = await extractNlIntent({ + root: process.cwd(), + sourcePath: 'project/ticket-079/README.md', + text: GOVERNED_TICKET_README, + }, config); + + assert.equal(result.records[1]?.statement.action, 'validate'); + assert.match(result.records[1]?.statement.text ?? '', /^AC-01:/); + assert.match(result.records[1]?.statement.text ?? '', /membership list from the session/); + assert.deepEqual(result.records[1]?.source.lines, { start: 16, end: 17 }); + assert.equal(result.records[2]?.statement.action, 'validate'); + assert.deepEqual( + (result.records[1]?.metadata.missingFields as string[] | undefined) ?? [], + [], + ); +}); + +test('generic TASK.md line segmentation stays unchanged for headings', async () => { + const config = makeConfig(process.cwd()); + const result = await extractNlIntent({ + root: process.cwd(), + sourcePath: 'docs/TASK.md', + text: '# Status\n\n- Owner must approve the patch before merge.\n', + }, config); + assert.equal(result.records.length, 1); + assert.match(result.records[0]?.statement.text ?? '', /Owner must approve/); + assert.equal(result.records[0]?.source.extractor, 't2c/nl-heuristic@1'); +}); diff --git a/test/docs.test.ts b/test/docs.test.ts index 3a49759..58e8fc1 100644 --- a/test/docs.test.ts +++ b/test/docs.test.ts @@ -4,6 +4,7 @@ import os from 'node:os'; import path from 'node:path'; import test from 'node:test'; import { extractDocumentationBaseline } from '../src/extractors/docs-deterministic.js'; +import { T2C_VERSION } from '../src/version.js'; import { makeConfig } from './helpers.js'; test('deterministic documentation baseline records headings, code blocks and explicit references', async () => { @@ -32,7 +33,7 @@ test('deterministic documentation baseline records headings, code blocks and exp assert.ok(result.records.every((record) => record.source.kind === 'document')); assert.ok(result.records.every((record) => record.source.extractor === 't2c/markdown-documentation@2')); assert.ok(result.records.every((record) => record.metadata.generation.generator === 't2c/markdown-documentation')); - assert.ok(result.records.every((record) => record.metadata.generation.runtimeVersion === '0.5.0')); + assert.ok(result.records.every((record) => record.metadata.generation.runtimeVersion === T2C_VERSION)); const reference = result.records[1]; assert.deepEqual(reference?.statement.target.paths, ['src/runtime.ts']); assert.deepEqual(reference?.statement.target.symbols, ['validateContract']); diff --git a/test/pipeline.test.ts b/test/pipeline.test.ts index 4aae4d0..49e8fbf 100644 --- a/test/pipeline.test.ts +++ b/test/pipeline.test.ts @@ -13,6 +13,7 @@ import { runPipeline } from '../src/pipeline/run.js'; import { parseEventLog } from '../src/pipeline/event-log.js'; import { canonicalPipelineManifestEvidence } from '../src/pipeline/event-log-persistence.js'; import { executeAction } from '../src/services/actions.js'; +import { T2C_VERSION } from '../src/version.js'; import { makeConfig } from './helpers.js'; const exec = promisify(execFile); @@ -54,7 +55,7 @@ test('Offline pipeline writes a complete run', async () => { assert.equal(result.manifest.llm.summary, false); assert.equal(result.manifest.status, 'degraded'); assert.equal(result.manifest.failure, null); - assert.equal(result.manifest.runtime.version, '0.5.0'); + assert.equal(result.manifest.runtime.version, T2C_VERSION); assert.equal(result.manifest.stages.naturalLanguageExtraction.status, 'fallback'); assert.equal(result.manifest.stages.naturalLanguageExtraction.reason?.code, 'LLM_NOT_CONFIGURED'); assert.equal(result.manifest.stages.markdownExtraction.status, 'fallback'); diff --git a/test/plan-create-llm.test.ts b/test/plan-create-llm.test.ts new file mode 100644 index 0000000..064bc7e --- /dev/null +++ b/test/plan-create-llm.test.ts @@ -0,0 +1,84 @@ +import assert from 'node:assert/strict'; +import { promises as fs } from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; +import test from 'node:test'; +import { buildRecord } from '../src/core/record.js'; +import { diagnoseGraph } from '../src/graph/diagnostics.js'; +import { linkIntentRecords } from '../src/graph/linker.js'; +import { + createRepositoryPathProbe, + proposeCodeChangePlans, +} from '../src/synthesis/code-change-plan.js'; + +const AT = '2026-07-30T15:00:00.000Z'; + +test('descriptive update intents do not create missing nested paths', async () => { + const root = await fs.mkdtemp(path.join(os.tmpdir(), 't2c-plan-desc-')); + await fs.mkdir(path.join(root, 'src/php_app/config'), { recursive: true }); + await fs.writeFile(path.join(root, 'src/php_app/config/emails.json'), '{}\n'); + const descriptive = buildRecord({ + kind: 'todo_item', + action: 'change', + object: 'deployment documentation', + target: { + paths: [ + 'platform/scripts/deploy-stack.sh', + 'src/php_app/config/emails.json', + ], + }, + text: 'Update deployment documentation mentioning platform/scripts/deploy-stack.sh and src/php_app/config/emails.json.', + lifecycle: 'planned', + sourceKind: 'todo', + sourcePath: 'docs/ops.md', + sourceLines: { start: 4, end: 4 }, + extractor: 'test/plan-create-llm', + epistemicClass: 'plan', + confidence: 0.95, + basis: ['fixture'], + }); + const graph = linkIntentRecords([descriptive], AT); + const diagnostics = diagnoseGraph(graph, AT); + const result = proposeCodeChangePlans({ + graph, + diagnostics, + generatedAt: AT, + pathExists: createRepositoryPathProbe(root), + }); + assert.deepEqual( + result.plans[0]?.changes.map((change) => `${change.action} ${change.path}`), + ['modify src/php_app/config/emails.json'], + ); + + const explicit = buildRecord({ + kind: 'todo_item', + action: 'add', + object: 'deployment documentation', + target: { + paths: [ + 'platform/scripts/deploy-stack.sh', + 'src/php_app/config/emails.json', + ], + }, + text: 'Create platform/scripts/deploy-stack.sh and update src/php_app/config/emails.json.', + lifecycle: 'planned', + sourceKind: 'todo', + sourcePath: 'docs/ops.md', + sourceLines: { start: 4, end: 4 }, + extractor: 'test/plan-create-llm', + epistemicClass: 'plan', + confidence: 0.95, + basis: ['fixture'], + }); + const explicitGraph = linkIntentRecords([explicit], AT); + const explicitResult = proposeCodeChangePlans({ + graph: explicitGraph, + diagnostics: diagnoseGraph(explicitGraph, AT), + generatedAt: AT, + pathExists: createRepositoryPathProbe(root), + }); + assert.deepEqual( + explicitResult.plans[0]?.changes.map((change) => `${change.action} ${change.path}`), + ['create platform/scripts/deploy-stack.sh', 'modify src/php_app/config/emails.json'], + ); +}); diff --git a/test/python-runtime.test.ts b/test/python-runtime.test.ts index ad1a198..664aa74 100644 --- a/test/python-runtime.test.ts +++ b/test/python-runtime.test.ts @@ -7,6 +7,7 @@ import { promisify } from 'node:util'; import test from 'node:test'; import { buildRecord } from '../src/core/record.js'; import { linkIntentRecords } from '../src/graph/linker.js'; +import { T2C_VERSION } from '../src/version.js'; const execFileAsync = promisify(execFile); @@ -34,7 +35,7 @@ test('Python package executes the local TypeScript reality runtime without a ser 'import os', 'from todo2code import TypeScriptRuntime', 'runtime = TypeScriptRuntime(os.environ["T2C_TEST_ROOT"], cli_path=os.environ["T2C_TEST_CLI"])', - 'assert runtime.version() == "todo2code 0.5.0"', + `assert runtime.version() == "todo2code ${T2C_VERSION}"`, 'run = runtime.pipeline(task_file=None, todo_file=None, changelog_file=None, documents=(), output_dir=".intent-python", git_count=1)', 'assert run["manifest"]["status"] == "succeeded"', 'assert run["manifest"]["stages"]["summary"]["status"] == "skipped"',