Skip to content

[WIP] DevMuse 3.0 — release integration - #81

Draft
huiyu wants to merge 70 commits into
mainfrom
3.0
Draft

[WIP] DevMuse 3.0 — release integration#81
huiyu wants to merge 70 commits into
mainfrom
3.0

Conversation

@huiyu

@huiyu huiyu commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Integration branch for the DevMuse 3.0 release. The adversarial audit's blockers are now all cleared; this remains a draft pending the final release checklist (version bump, changelog, tag).

This PR collects the full DevMuse 3.0 body (GitHub-first context #62, living PRD/architecture #63, case registry + mu-setup #68, cross-model review #51, Codex dispatch #54, auto-judge #41, model-churn #44, mu-retro removal #66) on top of the v2.2.0 release.

A four-workstream adversarial audit originally found the work was "clean modules, unit-tested in isolation, wired to nothing." All 20 inline review threads are now resolved, closed by fix PRs #82#89 (each verified against code). Full detail — including the tracked residual risks R1–R4 (post-3.0 live-integration work, not blockers) — lives in docs/3.0-release-readiness.md.

Release blockers — all cleared

Per-issue release-readiness

Issue Verdict
#68 registry Loop closed; approval-gated in code; UC-C9 precedence real (#83/#87/#89). Live provider transport is post-3.0 (R2)
#51 cross-review Runs for real; hardened env + private temp (#84/#85). Live smoke test binary-gated in CI (R3)
#41 auto-judge False-pass vectors closed; Fable 5 sweep re-run (#82)
#63 living PRD/arch Four axes + composed mu-prd + de-gated mu-model + test:profiles (#88)
#62 project-context update-cache writer + lock retry + selection/lifecycle correctness (#85/#86). Behavioral prompts still string-match (R1)
#44 model-churn Grades its own fresh transcript (#82)
#66 / #54 done / scope-complete

Remaining before v3.0.0: release mechanics (version bump, changelog, tag) and a decision on the residual risks R1–R4 (all deferrable to release notes).

Relates to #62 #63 #68 #51 #54 #41 #44 #66

huiyu and others added 15 commits August 21, 2026 10:52
Implements the GitHub-first project-context foundation for #62: repository-identity
resolution, worktree-safe recoverable cache, operation-scoped capability and
authorization, managed Issue/PR revision blocks, delivery-lifecycle projection,
and the pipeline skill/adapter bindings — with offline/non-GitHub fallback intact.

Covers UC-G1..UC-G10 and UC-GR1..UC-GR3. Hardened after independent design, code,
coverage, and security review (fail-closed authorization binding, manifest and
default-branch-ref injection defenses, managed-publisher secret gate, deterministic
hash/splice CLI commands, CI coverage for the new suites).

Relates to #62
Resolves #66. Periodic Git-summary retrospection did not earn a conversational
skill: its trigger was a calendar interval, its subject arbitrary Git activity
rather than an outcome-bearing unit, and its output a committed summary with no
named downstream consumer. The value in the one existing retro came from
analyzing a completed campaign, not from periodic Git statistics — a script or
CI report is the right home for commit counts and churn.

Removes the source skill, generated Codex adapter, routing pointer and
on-demand category entry, README and README_CN inventory rows, the domain-model
example in CONTEXT.md, the adapter UI descriptor, and the platform-compat
expectation. Historical retro artifacts under docs/retro/ are preserved as
history.

Closes #66


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Resolves #41. Transcripts were judged by hand against the README criteria
table. This adds a subagent judge that scores a transcript against those same
criteria, without duplicating them.

- parse-criteria.mjs reads the README criteria table as the single source of
  truth (no second copy to drift)
- judge.mjs builds the grading prompt and parses the verdict; overall is
  recomputed from sub-verdicts so a failed criterion cannot pass, and an
  unparseable judge response is an error rather than a silent pass
- judge.sh runs a headless claude judge over a transcript; run-test.sh gains
  a --judge flag to run-and-score in one step
- judge.test.mjs covers the parser and verdict logic deterministically (no
  model), wired as test:regression-judge in CI; it also asserts prompts and
  criteria rows stay in one-to-one correspondence

Closes #41


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Resolves #54. Codex rarely fans out on decomposable work while the Claude
adapter does, because the Codex adapter shipped no orchestration guidance and
Codex's manager is conservative by default.

Adds an opt-in HOST_POLICY section pointing out where DevMuse work decomposes —
independent mu-code tasks, mu-review lenses, mu-scope probes — expressed in
Codex-native terms (manager/worker roles, git-worktree isolation, config.toml
max_threads/max_depth). It is explicitly not behavior-tested on Codex, claims no
parity with the Claude adapter, and never overrides the host's manager. Single
source via build:adapters; platform-compat locks the opt-in constraints.

Also converts the untracked root AGENTS.md — a verbatim CLAUDE.md copy — into a
thin pointer to CLAUDE.md plus the Codex host-policy entry point, so the
maintainer contract has one home and cannot drift.

Documents the guidance in platform-support.md and its CN twin.

Closes #54


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Resolves #51. mu-review described optional review "by another model" but had no
executable path, and restoring the old Claude->Codex block unchanged would make
the generated Codex adapter review with Codex itself.

Adds a cross-review runtime that constructs a read-only, ephemeral,
project-scoped reviewer invocation with quoted argument arrays (no eval, no
shell, no aliases), prefers a local subscription login over an API key, and:

- routes reciprocally by host — Claude Code -> Codex, Codex -> Claude Code, other
  hosts use a configured different-family reviewer or have none
- never invokes the current host as its own reviewer and blocks recursive
  cross-review via a subprocess env guard (depth 1)
- runs under a bounded timeout; missing CLI, auth failure, timeout, non-zero
  exit, or malformed output falls back without blocking the primary review
- validates structured output over exit code, normalizes findings with reviewer
  provenance, and surfaces contradictions side by side

The canonical mu-review policy references the runtime; the adapter build vendors
it into mu-review and rewrites the reviewer direction and current_host per host.
Fake-binary tests assert exact args/env, recursion and same-family guards,
timeout/fallback, and output validation with no network. platform-compat locks
the reciprocal rewrite; docs updated with CN twin.

Closes #51


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…reframe (#73)

Part of #63 (foundation stage). Design in
docs/specs/2026-08-24-living-prd-architecture-design.md.

The survey showed the target is closer than #63 implies: mu-prd is already
living, mu-wiki already owns a living architecture set, and #62's manifest
already nests artifacts.architecture.{index, domain_model}. So the domain model
is not an orphan to relocate — it is the manifest-declared domain_model member
of the architecture set.

This foundation stage:
- adds knowledge/principles/project-profiles.md: the smallest useful profile set
  plus the "common core + profile + concern-triggered sections" composition rule,
  with the no-empty-slot-commitment and stateless-degradation guards
- extends the concern triggers (nfr-checklist.md) with the two concerns #63 names
  that were absent: AI/model/tool boundary, and accessibility/localization
- reframes domain-model.md: CONTEXT.md is the manifest-declared architecture-set
  member, its modeling method runs inside the mu-prd/mu-arch flow, and mu-model
  is the optional dedicated tool rather than a required gate
- references profiles + concerns from mu-arch's C4 positioning step

Deferred to later stages (per the design's staged delivery): the mu-prd
section-model rewrite, the flat project-type table replacement, CLAUDE.md
wording, packaged examples, and UC-ID traceability wiring.

Regenerated adapters; all suites pass.

Relates to #63


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Part of #68 (design stage). Independent design review passed; all 15 use cases,
9 mu-setup contract points, 8 research tasks, and 12 acceptance criteria map to
a design section.

Resolves the three forks: Git-reviewable files are the canonical local backend
(SQLite an optional derived index); the manifest evolves v1->v2 with an explicit
`cases:` block behind a mu-setup presentation gate; cross-provider edges with no
provider home are canonical in DevMuse's repository registry. mu-setup is a thin
skill over a project-registry runtime that reuses #62's identity/cache/auth.

Review-hardening folded in: corrected the v1->v2 degradation claim (a v1 parser
returns unknown-key, not unsupported-schema, until its schema-version test is
reordered — now a scoped stage-1 task); defined the content-hash revision model
and result-anchored staleness; fixed the ADR-0001 mis-citation; each delivery
stage is its own plan boundary.

Relates to #68


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…adation (#75)

Part of #68 (implementation stage 1: research + contract). Design in
docs/specs/2026-08-24-case-registry-design.md.

- Reorder the project-context manifest parser to test schema_version before the
  unknown-key screen, so a future-versioned manifest (v2's `cases:` block)
  degrades to `unsupported-schema` — "your DevMuse is older than this manifest" —
  instead of `unknown-key`, which read as corruption (UC-C8, AC#9). v1 behavior,
  including unknown-key detection for schema_version:1, is unchanged.
- Add the plugin/runtime/project-registry contract runtime (standalone; no skill
  consumes it yet, so it is not vendored):
  - routing.mjs — five asset kinds, the `cases.routes` vocabulary, validation
    with default fill, and per-kind provider resolution
  - registry.mjs — content-hash asset revision (stable, content-only), asset
    validation, locators, and deterministic Git-reviewable serialize/parse that
    sorts by id and rejects a hand-edited revision
  - staleness.mjs — result-anchored coverage staleness across the four revision
    axes (UC-C10, AC#11)
  - migration.mjs — v1->v2 proposal that never writes (present-before-write)
  - cli.mjs / index.mjs
- 8 contract tests + a v2-degradation test on the reordered parser; wired as
  test:project-registry in CI.

Regenerated adapters (vendored manifest copies). Deferred to stage 2: the local
registry file store wired into mu-setup.

Relates to #68


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
#76)

Part of #68 (implementation stage 2). Makes the case registry usable on the
repository-backed local path, with no SaaS account and no database runtime.

- project-registry/store.mjs: Git-reviewable local backend — registryPath,
  readKind (absent = empty, not error), atomic writeKind, idempotent
  initRegistry (existing kind files kept, not overwritten — UC-C5), and a
  non-mutating registryStatus. serializeRegistryFile now validates every asset
  and its kind before writing, so the store never persists garbage.
- CLI gains init / status / read-kind / write-kind (repo-resolved paths).
- plugin/skills/mu-setup: the discover -> propose -> approve -> init/migrate
  workflow, reusing project-context for identity/capability/authorization and
  the project-registry CLI for proposal + store. Idempotent, present-before-
  write, stores no credentials (UC-C3/C5/C6/C7).
- Registered mu-setup as an on-demand skill: build ui map, both runtimes
  vendored, platform-compat roster, README(+CN) inventory, bootstrap routing and
  on-demand list, CONTEXT.md example.
- 5 store tests (init idempotency, no-overwrite rerun, empty/valid, status,
  invalid-asset rejection). test:project-registry now covers the directory.

Regenerated adapters (13 skills). Deferred to stage 3: a reference provider
adapter with fake-provider tests.

Relates to #68


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…dapter (#77)

Part of #68 (implementation stage 3). Proves the provider contract with one
worked adapter and the outage/migration state machine, all testable with
fixtures (no network).

- provider.mjs: the per-kind adoption/outage/migration state machine. Its
  load-bearing invariant — a temporary outage moves to PendingSync and NEVER
  silently demotes to Local (UC-C6); the only path back to Local is an explicit,
  approved force-local. Migration requires approval plus a complete old->new id
  map, preserved on success (UC-C7). classifyOutcome separates transient
  unavailability (-> outage) from an auth denial (never an outage).
- providers/xray.mjs: the reference adapter (Xray via Jira). Declares a
  design-time capability model (validated_against_live: false until a live
  check), builds a project-scoped read request that carries NO credentials (the
  transport applies auth), and normalizes a provider test record into a registry
  reference + revision cursor — never a drifting payload copy.
- CLI + index exports; 7 provider tests (adoption/outage/migration guards,
  outcome classification, request has no credentials, normalization).

Regenerated adapters (mu-setup vendors the runtime). Deferred to stage 4: skill
wiring + UC-ID traceability through the pipeline.

Relates to #68


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Part of #68 (implementation stage 4, final). Wires the case registry into the
pipeline so a use case is traceable from requirement through test result.

- knowledge/principles/case-registry.md: the traceability contract — five asset
  kinds with stable IDs, the PRD->scope->arch->plan->code->review spine (stages
  reference IDs, never restate prose), and result-anchored coverage staleness via
  the project-registry runtime. Additive: where no registry exists, stages behave
  as before.
- mu-scope/arch/plan/code/review each reference it at their project-context
  binding: scope owns the delivery delta over referenced cases; arch cites case
  IDs; plan/code carry IDs through tasks and tests; review-coverage marks stale.
- mu-reviewer's review-coverage output gains the "Stale" status: a case with a
  test+result reads stale, not covered, when a bound revision moved — computed
  with the runtime's staleness command, not by hand.
- github-first-contract asserts every pipeline stage references the contract and
  the reviewer marks staleness.

Regenerated adapters (case-registry.md vendored into all five pipeline skills).
Completes the four-stage #68 implementation.

Relates to #68


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* feat(prd): #63 stage 2 — profile-composed sections and diagram selection

Part of #63 (stage 2). Replaces one-size-fits-all output with profile
composition, using the project-profiles.md set from stage 1.

- architecture-assessment.md: the flat "Diagram Type by Project Type" table
  becomes "Diagram Type by Profile" — diagram selection follows the same profile
  lens that composes document sections, so the project is classified once and
  reused; profiles compose (union of diagram sets).
- mu-prd: "Depth Mode Selection" becomes "Profile and Depth Selection" — two
  orthogonal axes. Profile selects WHICH sections exist (a client-app has IA,
  flows, screens, tiering; a library/CLI has a public surface and no screens; a
  data/AI product has data-flow and model/tool-boundary sections); depth selects
  HOW MUCH of each. The existing full section list is now explicitly the
  client-app profile, so a user-facing product behaves as before. No section is
  emitted for a slot the profile does not populate from evidence (UC-DR2).

Regenerated adapters (project-profiles.md vendored into mu-prd). Behavioral
prd-state-modeling re-validation runs in #44. Deferred to stage 3: packaged
worked examples.

Relates to #63

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

* feat(examples): #63 stage 3 — packaged worked examples

Part of #63 (stage 3). Packages worked examples so an agent or user can see the
intended shape of profile- and concern-composed output (UC-D9).

- knowledge/examples/README.md + reference-booking.md: a broad stateful-service
  reference case exercising state, transactions, concurrency, async delivery,
  multitenancy, a public API, and SLOs — showing which sections the composition
  emits and, crucially, which it leaves out (an excluded "payment" state the
  profile offers but evidence does not populate). The DevMuse dogfood domain
  model is the repository's own CONTEXT.md, referenced not copied.
- Both files carry the UC-DR3 banner: illustrative knowledge, never this
  repository's own product truth.
- Referenced from project-profiles.md so they are discoverable and vendored.

Regenerated adapters. Behavioral prd-state-modeling re-validation of the stage-2
skill-prose changes runs in #44.

Relates to #63

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…action (#80)

Resolves #44. Establishes the model-churn regression routine — rerun the whole
prd-state-modeling suite on every default-model change, because each model
release re-breaks skill triggering.

- run-all.sh: runs every scenario through headless claude, auto-judges each
  against the README criteria via judge.sh (the #41 judge), aggregates a
  pass/fail summary, and exits non-zero on any regression. SCENARIOS= runs a
  named subset.
- extract-result.mjs: pulls the assistant's final text from a `claude -p
  --output-format json` run, handling BOTH the single-{result} object and the
  stream-event ARRAY shapes (whose final type:"result" element carries the
  text). judge.sh used only the object shape, so it fed the judge a raw event
  array and every real run misjudged; both the transcript and judge-response
  extractions now share this helper. 4 deterministic tests.
- Documented the routine in docs/testing.md and its CN twin.
- test:regression-judge now covers the whole test directory.

Validated on Fable 5: stateless-cli-no-trigger passes — the model classified the
project as the cli-devtool profile (the #63 stage-2 framing), the object-model
trigger correctly did not fire, and only the three lightweight sections were
produced. Full-suite sweep recorded on the issue.

Closes #44


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Adversarial four-workstream audit after the 3.0/main split. Records the concrete
gaps between the merged 3.0 work and each issue's acceptance criteria, verified
against code and the installed codex/claude binaries. Living doc; update as gaps
close. Five release blockers identified (open-loop registry, dead cross-review
paths, judge false-pass); recommended fix sequence starts with judge integrity.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

@huiyu huiyu left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adversarial release-readiness audit — inline blockers/highs below, each resolvable as its fix lands. Full detail: docs/3.0-release-readiness.md. Fix order: judge integrity (#41/#44) → #68 loop → #51 run → #63 compose → #62 writer+CI.

Comment thread plugin/runtime/project-registry/migration.mjs
Comment thread plugin/runtime/project-registry/store.mjs
Comment thread plugin/runtime/cross-review/reviewer.mjs Outdated
Comment thread plugin/runtime/cross-review/reviewer.mjs
Comment thread plugin/runtime/cross-review/runner.mjs Outdated
Comment thread tests/prd-state-modeling/judge.mjs Outdated
Comment thread tests/prd-state-modeling/judge.mjs Outdated
Comment thread tests/prd-state-modeling/run-all.sh Outdated
Comment thread plugin/runtime/project-context/cache.mjs Outdated
Comment thread plugin/knowledge/principles/project-profiles.md Outdated
huiyu and others added 2 commits August 24, 2026 03:56
…grading (#82)

Addresses the release-readiness blockers on the auto-judge (#41) and model-churn
routine (#44) — the judge could pass a scenario it never graded, undermining
every judged result.

- parseVerdict rejects an empty criteria array (B5: [].every() === true would
  pass) and, given an expected count, rejects a short array (H1: a judge that
  drops the criteria it would fail). A missing/malformed per-criterion verdict is
  no longer a pass.
- judge.sh threads the scenario's criteria count (new `judge.mjs --count`) into
  `--parse`, adds `set -o pipefail`, and the CLI now exits 2 on a judge/setup
  fault, distinct from 1 (regression) — so run-all.sh stops mislabeling a broken
  judge as a skill regression (M4).
- run-all.sh captures the run's OWN transcript path (run-test.sh now emits
  TRANSCRIPT_PATH/TRANSCRIPT_STATUS) and marks ERROR when no fresh transcript
  exists, instead of judge.sh auto-selecting a prior model's stale file (H2).
- Split the vague-groupbuy criteria cell so its six gaps grade independently (M5,
  now 7 criteria); fixed extract-result.mjs's CLI guard (L1).
- 5 new unit tests (empty, subset, count, malformed verdict, criteriaCount).

The '9/9 Fable 5 PASS' should be re-run under this hardened judge before it is
trusted. Relates to #41 #44.


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
huiyu and others added 2 commits August 24, 2026 04:06
…proval gate (#83)

Addresses the #68 ship-blockers from the release-readiness audit: the registry
was an open loop — after mu-setup wrote a v2 manifest nothing could read it back,
nothing serialized the YAML, and the CLI wrote tracked files with no approval.

- **B1** project-context manifest parser now understands schema_version 1 AND 2:
  a v2 manifest's optional `cases:` asset-router block parses and is captured in
  value.cases (provider-token semantics validated downstream, not here). Only
  schema 3+ degrades to unsupported-schema. cases is optional and rejected under
  v1.
- **B2** new project-registry/manifest-io.mjs: serializeManifest renders a
  manifest value (v1 members + cases) as YAML the parser accepts, and readRouting
  validates the parsed cases block into a usable router. The loop closes:
  propose → serialize → parse → resolveProvider.
- **H3** the CLI's init/write-kind/write-manifest are now gated on
  `approved: true` (present-before-write, enforced in code); the false "no tracked
  write" claims in cli.mjs, case-registry.md, and mu-setup are corrected. New
  write-manifest command serializes + writes .devmuse/project.yaml, never secrets.
- release.yml now runs test:project-context/project-registry/cross-review (the
  3.0 features' own tests were absent from the release gate — audit MEDIUM 6).
- 3 loop tests (in-memory round-trip, through-disk round-trip via CLI, approval
  gate) + updated manifest tests for v1/v2/v3.

Relates to #68. Resolves PR #81 threads B1/B2/H3.


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

@huiyu huiyu left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Supplemental acceptance review on 3.0 at a3e4333, after #82 and #83.

The earlier B1/B2/B5 findings are fixed. The new inline findings below are independently reproducible and should keep #62, #68, and #51 open.

Two issue-level acceptance gaps also remain:

  • #63 is still not the contract defined by #63/#67. There is no shared module-card schema, four-axis selector, generated matrix, composed renderer, or positive/reverse fixture suite. mu-prd still says not to enumerate use cases and delegates them to mu-scope, while the case-registry contract says mu-prd owns Product Use Cases. PRD output remains docs/prd/YYYY-MM-DD-*; current-state architecture still routes to standalone mu-wiki; mu-arch still emits dated change specs; and the architecture template still assumes containers, services, databases, queues, and endpoints. This is a profile-aware prose foundation, not the living PRD/architecture product loop.
  • #68 still lacks an end-to-end data plane. mu-setup mentions user preferences but has no user-level store, schema, loader, writer, or precedence implementation; mu-prd has no registry integration; the Xray module is still a descriptor with no transport/sync path; and there is no setup → PRD → scope → arch → test-result fixture. The v2 manifest loop now closes, but the issue acceptance loop does not.

Release gating should therefore require one executable end-to-end fixture for #63/#68, plus the correctness and security fixes in the inline threads. Keep PR #81 Draft until those issue contracts, rather than only the narrowed unit contracts, pass.

Comment thread plugin/runtime/cross-review/cli.mjs Outdated
Comment thread plugin/runtime/cross-review/runner.mjs Outdated
Comment thread plugin/runtime/project-context/cache.mjs Outdated
Comment thread plugin/runtime/project-context/managed-block.mjs
Comment thread plugin/runtime/project-context/lifecycle.mjs Outdated
Comment thread plugin/runtime/project-registry/registry.mjs
Comment thread plugin/runtime/project-registry/staleness.mjs Outdated
Comment thread plugin/runtime/project-registry/store.mjs
Comment thread plugin/runtime/project-registry/providers/xray.mjs
Comment thread plugin/skills/mu-setup/SKILL.md Outdated
…capture (#84)

Addresses the #51 ship-blockers: both reviewer paths were functionally dead —
the Codex command used flags codex rejects, and the Claude path's output was
never captured.

- **B3** codex argv corrected against the installed codex 0.149.1: `--base
  <branch>` (a branch, extracted from the range — not `--base-ref` with a
  range), `--output-schema <file>`, and `CODEX_HOME` env (not `--config-home`).
- **B4** output capture fixed: `--output-schema`/`--json-schema` are passed so
  reviewers emit structured JSON; the runner now DRAINS stdout (an un-drained
  pipe deadlocked the Claude path until the 180s timeout) and reads per
  outputMode — codex from its output file, claude from stdout.
- **M1** Claude reviewer hardened: read-only tool allowlist (Read/Glob/Grep),
  `CLAUDE_CONFIG_DIR` env (not `--settings`). **M2** env overrides implemented
  (DEVMUSE_CROSS_REVIEW_BINARY / _CONFIG_HOME / _TIMEOUT_MS). **M3** runReview
  owns a private 0700 temp dir for the output schema + result and cleans it up.
  **L2** the blind adapter substitution is fixed — the Codex mu-review now reads
  "Codex skills invoke their vendored ..." via a dedicated build collapse.
- **Live flag-acceptance smoke test** (skipped when binaries absent, but ran
  green here against codex 0.149.1 / claude 2.1.241): asserts every built flag
  is listed in the CLI's own --help — the gate the fake-spawn tests could not
  provide, and which would have caught B3.

18 cross-review tests pass (incl. stdout-mode drain, runReview temp-dir cleanup,
env overrides, baseBranch extraction). Relates to #51. Resolves PR #81 threads
B3/B4a/B4b. The trigger remains appropriately model-gated (H3).


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…ection (#85)

Addresses the security/correctness findings from the external review of PR #81.

- **CRITICAL (#51)** cross-review no longer forwards the whole process.env to the
  reviewer subprocess (it held API tokens visible in the invocation and any log).
  buildInvocation now copies a strict allowlist (PATH/HOME/locale…) plus the
  recursion guard and auth home; `plan` prints only env KEY NAMES, never values.
- **#51** runner: a synchronous spawn failure hit a timer temporal-dead-zone and
  threw ReferenceError instead of the typed fallback — the timer binding is now
  declared before `done`. A non-zero reviewer exit is a fallback, not trusted
  output.
- **#68** store: `writeKind` resolves the real path and rejects a `registry` dir
  that symlinks outside the repo, so an approved write can never land elsewhere.
- **#68** xray: baseUrl is parsed and restricted to a clean https origin+path
  (no userinfo/query/fragment); `since` and the record's `updated` must be ISO
  instants; a record key must be PROJECT-NNN — closing the JQL-injection and
  malformed-record surfaces.
- Regression tests for each (env allowlist, sync-spawn fallback, non-zero exit,
  symlink escape, URL/since/record validation).

Relates to #51 #68. Resolves the PR #81 env-leak, spawn-failure, symlink, and
xray review threads.


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Addresses the #62 correctness findings from the external review of PR #81.

- **lifecycle** — a required-PR-remaining check from MergedPendingDelivery no
  longer transitions backward to Reviewing (that reopened review after merge and
  broke monotonicity); it preserves the current state.
- **cache mergeCache** — progressive same-work enrichment (issue → PR → phase)
  now merges in place instead of returning needs-reconciliation, so the cache can
  evolve through the delivery lifecycle; reconciliation is reserved for a
  contradictory shared value or a changed work_id.
- **cache acquireLock** — a broken stale lock now retries the acquire ONCE and
  persists the current write, rather than dropping it to memory-only and letting
  only the next call benefit.
- **managed-block selectCurrentManagedRevision** — selection is bound to the
  expected workId (and issue for plans); a foreign block with a higher revision
  in a comment can no longer win. The CLI passes these through.
- 4 regression tests (backward-transition guard, foreign-block filtering,
  progressive enrichment, stale-lock persistence).

Relates to #62. Resolves the PR #81 lifecycle, cache, and managed-block threads.


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
huiyu and others added 9 commits August 25, 2026 16:58
Per the maintainer's scope decision (2026-08-25), #47 (mu-model create
field-acceptance) is descoped from the 3.0 milestone and tracked post-3.0. With
its PR #81 thread resolved as a scope decision, all 37 review threads across the
four review passes are resolved.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT
…#68) (#105)

Fourth-pass re-verification found campaign 4's fixes were only partial:

- atomicWrite fixed the symlink-escape but left the temp file behind when the
  write or rename failed (the "cleanup on failure" requirement). It now removes
  the temp file on any failure path (never a half-written .tmp-* left behind).
- providerTransition migrate rejected null/empty idMaps but still accepted an
  EMPTY target locator, and dropped the locator history and cross-asset links. It
  now requires every idMap target to be a non-empty locator, requires the old->new
  locator history (id -> {from,to}) for every migrated asset, requires links to be
  a well-formed list, and preserves history + links + provenance in the record
  (UC-C7). (Also fixed a latent throw: history validation short-circuits on an
  invalid idMap instead of calling Object.keys(null).)

Tests: temp cleanup on a failed rename; empty-target / missing-history /
dropped-links rejected; history + links preserved on success. Adapters regenerated.


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…heuristic (#51) (#106)

Completing the #51 codex-output finding that campaign 4 only partially addressed:

- normalizeExternalFindings returned {status:ok} with a junk finding for
  {findings:[null]} (item?.severity → "minor", summary → ""). A finding must now
  be an object with a non-empty summary; null/shapeless entries are dropped, and a
  non-empty list that yields NO usable finding is `malformed-findings` (invalid),
  not a silent clean review. A mix keeps the valid finding and drops the junk.
- extractCodexReviewFindings treated ANY text containing a clean sentinel as
  clean, so a long changed-format report merely mentioning "no issues" was judged
  clean. The clean path now also requires the text be short (<=240 chars) and carry
  no [P*] marker; long unfamiliar prose is unrecognized → the runner degrades.

Tests: {findings:[null]} / all-shapeless → invalid; mix drops junk; long prose
mentioning "no issues" → unrecognized. Adapters regenerated.


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…nical guide (#54) (#107)

Completing #54: campaign 4 corrected the config keys but left the design's core
requirement — per-skill opt-in pointers (skills may not load HOST_POLICY) plus
eligible/ineligible/declined coverage.

- A single CONCURRENT_DISPATCH map is now the source of truth; both the HOST_POLICY
  section bullets and each eligible skill's own per-skill pointer derive from it, so
  they cannot drift.
- The eligible skills (mu-code, mu-review, mu-scope) each carry an opt-in dispatch
  pointer in their Codex SKILL.md that cites the canonical HOST_POLICY guide and
  states the declinable/opt-in nature ("a conservative manager may decline, and
  concurrency is never forced"). Ineligible skills carry nothing.
- platform-compat test asserts eligible-has-pointer, ineligible-has-none, the
  declined affordance, and that each per-skill note matches the canonical HOST_POLICY
  text (no drift).

Adapters regenerated.


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…hreads truly resolved

A per-item acceptance check found 4 of campaign 4's 6 fixes were only partial
(temp-file cleanup on failure, {findings:[null]}, empty migration target + dropped
history/links, per-skill dispatch pointers). Campaign 5 (PRs #105-#107) completed
all four with reverse tests. All 37 PR #81 threads resolved; test:acceptance green.
Lesson one level up: a GitHub "Resolved" mark is not acceptance.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT
…d finding (#51) (#108)

Fifth-pass re-verification found the #51 boundary still incomplete at two exact
reverse cases:

- extractCodexReviewFindings("No issues could be checked because the review
  transport changed format.") was judged clean — the sentinel was matched anywhere
  in short text. CODEX_CLEAN is now anchored to an allow-list: the WHOLE trimmed
  verdict must BE a clean phrase, so a short abnormal output merely CONTAINING
  "no issues" is unrecognized (degrades) rather than clean.
- normalizeExternalFindings({findings:[null,{summary:"real"}]}) returned ok and
  silently dropped the malformed item. It now fails CLOSED: EVERY item must be a
  well-formed finding (object + non-empty summary), else malformed-findings
  (invalid). An empty array is still a clean review.

Tests: the exact short-error and mixed-item reverse cases, plus whole-verdict
clean phrases still recognized. Adapters regenerated.


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…nce (#68) (#109)

Fifth-pass re-verification found migration evidence was PRESENT but not internally
consistent — three exact reverse cases returned ok:

- locatorHistory[id].to disagreeing with idMap[id] (contradictory target) → now the
  recorded history target must AGREE with the canonical id-map target.
- blank provider/provenance/history/link fields (from:"", to:" ", provenance:" ",
  link fields "") → all string evidence is now trim-aware non-empty.
- omitting `links` was normalized to [] (can't distinguish "explicitly none" from
  "dropped") → `links` must now be an EXPLICIT array; an explicit [] is accepted,
  omission is incomplete.

Tests: contradiction, blank-field, omitted-links, and explicit-empty-links reverse
cases. Adapters regenerated.


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…nce (#54) (#110)

Fifth-pass re-verification: the static wiring tests do not satisfy #54's request
for eligible/ineligible/user-declined PROMPT behavior. Add a behavioral acceptance
suite that feeds a real model the ACTUAL shipped HOST_POLICY concurrent-dispatch
guidance and observes the dispatch DECISION:

- eligible (mu-review's independent lenses over one diff) -> PARALLEL
- ineligible (mu-prd authoring one artifact) -> SINGLE
- user-declined (explicit "run single-threaded") -> SINGLE

Verified stable across repeated live runs. Binary-gated on `claude` (a reasoning
proxy for the Codex-host decision logic; full Codex-host execution parity stays
out of scope by design). Wired into test:acceptance (and the anti-drift coverage
assertion). HOST_POLICY disclaimer refined to state the decision logic is now
behaviorally tested while Codex-host execution is not guaranteed. Adapters
regenerated.


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
A per-reverse-case re-verification found 3 campaign-5 fixes still failed specific
inputs (short-error clean, {findings:[null,item]} drop; contradictory/blank/omitted
migration evidence; #54 static-only). All fixed with the exact reverse tests,
including a real model behavioral suite for #54. All 37 PR #81 threads resolved;
test:acceptance green. New residual R5: the #54 behavioral test skips in CI
(binary-gated, no claude on the runner), verified stable locally.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT
Comment thread plugin/runtime/project-context/managed-block.mjs Outdated
Comment thread plugin/runtime/project-context/collaboration.mjs Outdated
Comment thread package.json Outdated
Comment thread plugin/runtime/cross-review/runner.mjs Outdated
Comment thread docs/3.0-release-readiness.md Outdated
huiyu and others added 6 commits August 25, 2026 22:08
…docs to the test:acceptance aggregate

- readiness doc: the "Residual risks" section was stale (missing R5, pre-campaign-3
  descriptions, and a stale "CI runs five / release runs three" line contradicting
  #97). Rewritten as R1–R5 plus explicit post-3.0 deferrals (#47, the PRD→registry→
  scope runtime harness), and the CI/release line now states both use test:acceptance.
- docs/testing.md + docs/testing_cn.md: the "Fast Deterministic Checks" block listed
  a stale subset of suites. Replaced with the single `npm run test:acceptance`
  aggregate (matching the doc's own "don't copy directory listings" philosophy),
  noting the binary-gated live tests skip when the model binary is absent. CN twin
  updated in the same commit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT
#62) (#111)

Sixth review pass — two blockers whose runtime was never actually changed:

- replaceManagedRevision spliced ANY new block over the body's block. Four illegal
  transitions were accepted: cross-work (work-A→work-B), backward revision (5→1),
  changed attempt_id, and scope→scope-revision. It now requires the old/new blocks
  to share kind, work_id, issue, and attempt_id (stable identity) and a strictly
  newer revision (a byte-identical same-revision re-post is an idempotent no-op).
- sanitizePublishable returned "safe" for password=…, sk-proj-*/sk-ant-api03-*
  keys, npm_* tokens, and credential-bearing postgres URLs — renderManagedRevision
  passes content as one string, so the object-key screen never saw them. Added
  value patterns for provider token prefixes, inline password assignments, and
  user:pass@ URLs; softened the "secret can never reach" comment to a best-effort
  filter (regex cannot guarantee arbitrary-secret detection).

Reverse tests: all four managed-revision transitions, and the five secrets rejected
end-to-end through renderManagedRevision. Adapters regenerated.


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…112)

Sixth review pass: the runner had no upper bounds — stdout/stderr accumulated
without limit, the output file was read whole, and the timeout was whatever the
caller/env supplied.

- stdout/stderr are capped at 5 MB total; past the cap the child is SIGKILLed and
  the run falls back (output-too-large) instead of exhausting memory.
- the output file is read through readCappedFile — a file over 5 MB falls back
  rather than being slurped in.
- the timeout is clamped to [1s, 600s] via clampTimeout, so a caller or
  DEVMUSE_CROSS_REVIEW_TIMEOUT_MS cannot set an unbounded (or zero) timeout.

Reverse tests: a >5 MB stdout flood kills the child and falls back; a >5 MB output
file falls back. Adapters regenerated.


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
) (#113)

Sixth review pass: test:acceptance was PATH-dependent — test:codex-dispatch (and
the cross-review live smoke) invoke real claude/codex when present, so the required
gate behaved differently across machines.

- All live/binary-invoking tests are now gated behind DEVMUSE_LIVE=1 (opt-in), so
  they skip in the gate regardless of which binaries are installed.
- test:codex-dispatch is removed from test:acceptance; the aggregate is now fully
  deterministic and makes no model calls.
- New `test:live` (DEVMUSE_LIVE=1) runs the cross-review smoke + codex-dispatch
  behavioral suite on demand / in a dedicated live gate.
- workflow coverage assertion no longer requires codex-dispatch in the aggregate;
  docs/testing (+ CN twin) document the deterministic gate vs opt-in live split.

test:cross-review now skips its 3 live tests without the flag (deterministic).


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sixth pass, minor: the go/no-go summary still said "every PR-#81 review thread is
resolved (30/30)" while the PR had grown to 42 threads across six passes. Rewrote
the top to state the current status is NOT release-ready, that "all resolved" has
been a premature claim more than once, and to defer to the live PR thread count as
the authoritative state — not a sentence in this doc.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT
-#113)

Two blockers (managed-revision identity binding + expanded secret screen) whose
runtime was never before changed, plus unbounded cross-review resources, a
PATH-dependent acceptance gate (now deterministic; live tests opt-in via
test:live), and a stale top summary. All 42 PR #81 threads resolved.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT
Comment thread docs/3.0-release-readiness.md Outdated
huiyu and others added 8 commits August 25, 2026 12:45
…sses (#62) (#114)

Seventh review pass — the campaign-7 blocker fixes missed further bypasses:

managed-revision (replaceManagedRevision):
- CRLF body corruption: parseDocument normalized the source before recording
  index/raw length, then the splice used the original CRLF body → misalignment +
  stray "-->". Now the body and candidate are normalized up front and spliced in
  the same normalized space.
- a -revision comment kind could be written into the body when no block existed →
  only BODY_KINDS (scope, plan) are accepted; scope-revision/plan-revision rejected.
- a valid block followed by arbitrary trailing text (a second marker or
  password=hunter2) was spliced verbatim → the candidate must be EXACTLY one
  complete block (raw === trimmed source), no leading/trailing content.

secret screen (inspectPublishable):
- free-form assignments api_key=/client_secret=/token=/secret=/OPENAI_API_KEY=
  returned safe → a single pattern now mirrors the sensitive-key vocabulary for
  raw `key = value` text. (The "append password after a legal block" bypass is
  closed by the exact-envelope check above.)

Reverse tests: CRLF splice, body -revision rejection, trailing-suffix rejection,
and the five free-form assignments through renderManagedRevision. Adapters
regenerated.


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
- R3/R5 and the residual-section closing line described the live tests as
  "skipping in CI"; after #113 they are opt-in (DEVMUSE_LIVE / test:live) and not
  in test:acceptance at all. Reworded to the accurate opt-in boundary. Historical
  rows keep their old state.
- Top summary bumped to seven passes; added the seventh-pass History row
  (campaign 8, PR #114 closed the reopened blockers' further bypasses).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT
…ocabulary (#62) (#115)

Eighth review pass — the #114 fixes still broke the body contract and left a
vocabulary gap:

managed-revision (replaceManagedRevision):
- it normalized the WHOLE body to LF, so surrounding human text lost its CRLF. Now
  the block is located by its markers in the ORIGINAL body and only that span is
  replaced — everything around it is preserved byte-for-byte.
- a byte-identical same-revision re-post now returns the ORIGINAL body unchanged
  (it no longer rewrites CRLF→LF).
- appending a scope block to a body that already holds a plan block created two
  managed blocks; it now raises managed-family-conflict (reconciliation needed)
  instead.

secret screen:
- the raw-string assignment pattern used a hand-reduced vocabulary that missed
  authToken=, authenticationToken=, authorizationToken=, oauth_cache=, oauthCache=.
  Both the object-key screen and the assignment screen now derive from ONE shared
  SENSITIVE_KEY_WORDS source, so they cannot drift.

Reverse tests: CRLF byte-preservation, idempotent-unchanged, cross-family conflict,
and the five camelCase/oauth-cache assignment variants. Adapters regenerated.


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…ed (campaign 9, #115)

The same managed-revision + secret-screen blockers reopened with subtler cases
(whole-body normalization losing CRLF, idempotent rewriting line endings,
cross-family two-block append; missing authToken=/oauth_cache= assignment
variants). All fixed in #115. 43/43 threads resolved. These two surfaces remain
the most-reopened; another pass is prudent before release.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT
…vision/body (#62) (#116)

Concentrated-review pass on the two most-reopened surfaces found three more gaps:

- quoted secret assignments bypassed the raw-string screen: token="secret",
  JSON "token": "secret", dotenv/shell export TOKEN="…" all returned safe because
  the value char class excluded quotes and the separator had to abut the key.
  SENSITIVE_ASSIGNMENT now allows an optional quote around the key and the value.
- a pathological revision (e.g. 400 digits) passed the unbounded /^[1-9]\d*$/
  regex, parsed to Infinity, and serialized to null. Revision and issue digits are
  now bounded (<=9), so such a header is malformed — fail closed.
- a non-string body was coerced to "" in replaceManagedRevision (and the CLI's
  `?? ""`), so the CLI exited 0 and silently discarded the original input. A
  non-string body now throws invalid-managed-body; null/undefined still mean a
  fresh create. The CLI passes body through so the error surfaces (non-zero exit).

Reverse tests: five quoted/dotenv/JSON secret shapes; a 400-digit revision →
malformed; non-string bodies → throw (function + CLI). Adapters regenerated.


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…n (campaign 10, #116)

The concentrated review found 3 more gaps on the two most-reopened files (quoted
secret assignments, 400-digit revision -> Infinity/null, non-string body coerced
to empty). All fixed in #116. 43/43 threads resolved.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT
…ain (#62) (#117)

Concentrated follow-up on the two most-reopened files found two more gaps:

- Markdown formatting bypassed the secret screen: `` `token`: … ``, **token**: …,
  [token]: …, <code>token</code>: … all returned safe because formatting sits
  between the key and separator (managed blocks ARE Markdown). The screen now scans
  BOTH the raw source and a conservative Markdown/HTML→plain-text projection
  (strips code/emphasis/reference markers, HTML tags, blockquotes). Benign Markdown
  (bold headings, inline-code identifiers, links, quotes) stays safe.
- the renderer accepted a wider numeric domain than the parser (revision/issue up
  to MAX_SAFE_INTEGER), so a rendered block could be malformed to its own
  selector/replacer. Both now share ONE domain (1..999_999_999 via
  validManagedNumber, matching the parser's [1-9]\d{0,8}); and non-string/missing
  content is rejected instead of being stringified to [object Object]/undefined.

Tests: a Markdown formatting matrix (dressed secrets rejected raw + through
renderManagedRevision, benign Markdown safe) and a render→select round-trip
invariant (999999999 selects, 1000000000/MAX_SAFE_INTEGER/0/1.5 refused, non-string
content refused). Adapters regenerated.


Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…en secret-detection architecture question

Markdown-dressed secrets + render/parse domain mismatch fixed in #117. 43/43
threads resolved. Flags the standing design decision the reviewer keeps raising:
regex secret detection can't be exhaustive; a structured-summary + field-allowlist
redaction boundary would be the durable fix. Best-effort framing documented.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KwyFyRC6pepaK6DuMK7YeT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant