Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,17 @@ _bmad-output/audit-reports/*/
# Delete these two lines to track them.
argusdemo/
bmad-dev-loop-pack/

# ⚠️ REGENERATED BY-PRODUCT, ignored 2026-08-29 — and the reason is a claim this repository
# has already published. `sprint-change-proposal-2026-08-10.md` records as MEASURED FACT that
# there is "No MSIX, PyInstaller, Briefcase, Nuitka, cx_Freeze, `.spec` or `.iss` anywhere in
# the tree". Committing `argus.spec` would falsify that line, and no guard would catch it.
#
# It is also load-bearing for nothing: `.github/workflows/build-binaries.yml` invokes
# `pyinstaller --onefile --name argus …` with CLI flags and never reads a spec file. The file
# appears when someone runs that command by hand — PyInstaller writes one as a side effect.
# Delete this line if a spec file ever becomes the real build input; then correct the proposal.
argus.spec

# Session scratch — working notes and one-off scripts, never part of the record.
scratch/
15 changes: 11 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,11 @@ necessary, not sufficient, and is recorded as LOCAL (architecture.md §H).

## Unreleased

_Nothing yet. The next consumer-visible change lands here._
### Added — Post-V1 E2E Integration & Verification Suite (`tests/test_post_v1_integration.py`)

Comprehensive end-to-end integration and verification suite (`tests/test_post_v1_integration.py`) validating Post-V1 capabilities across multi-language AST parsers (`TSParser`, `GoParser`, `JavaParser`), defect remediation engine (`RemediationEngine`, `verify_patch_dry_run`, `apply_patch` workspace path containment), and LSP diagnostic streaming (`LSPDiagnosticAdapter`, `LSPDiagnosticServer` over stdio and socket transports with standard JSON-RPC 2.0 Content-Length framing).

**Reachability, stated so this entry is not read as a shipped feature (added 2026-08-29):** the suite reaches all three packages **by direct import**. None of them is wired to a surface — no `argus` CLI subcommand proposes a patch, and no console script starts an LSP server. What this suite validates is library behaviour, not anything an operator or an editor can invoke. All three are disposed `library-seam` in the PRD (FR38/FR39/FR40).

---

Expand Down Expand Up @@ -883,7 +887,7 @@ to block, and flipping the default here would pre-empt a policy decision that be
### Packaging: what the distribution contains

`[tool.flit.module] name = "argus"` packages the `argus` Python package and nothing else. Measured on the
built artifacts: the wheel holds 96 modules plus the packaged command assets and metadata; the sdist adds
built artifacts: the wheel holds 108 modules plus the packaged command assets and metadata; the sdist adds
`pyproject.toml`, `README.md`, `LICENSE` and `PKG-INFO`. The RAM workflow directories (`audit/`,
`phases/`, `templates/`) and the installer scripts are **repository-only** — see README.md for the full
capability split. *(Amended 2026-08-15 by Story 12.7: the module figure moved with the tree, ~~`adapters/`~~
Expand All @@ -892,9 +896,12 @@ zero data assets — `flit_core` ships every file under `argus/`, so the command
with no build-backend change and reach the sdist because they are tracked.)*

Measured on the built wheel with this repository removed from `sys.path`, one clean subprocess per module:
**96 of the 96 shipped modules import.** None fail. (The figure read 73 of 73 when `0.1.0` was
**108 of the 108 shipped modules import.** None fail. (The figure read 73 of 73 when `0.1.0` was
written; it is DERIVED from the freshly built artifact by `TC-ArgusAgent-DOCS-001-54` — *the artifact
is the fact* — and moved to 95 on 2026-08-23 when Story 16.7 added
is the fact* — and moved to 108 on 2026-08-29 when Epic 20 added `argus/parsers` (3 modules,
Story 20.1), `argus/remediation` (4, Story 20.2) and `argus/adapters/lsp` (5, Story 20.3) — none of
which is reachable from any entry point, so the figure grew while the operator surface did not. It
moved to 95 on 2026-08-23 when Story 16.7 added
`argus/precision/silent_class.py`: the V2 SILENT predicate and the record that publishes the class
it derives as a question for a named human, promoting nothing and gating nothing. It moved to 94
earlier the same day when Story 16.5 added
Expand Down
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,10 @@ graded, but has no definition for the depth gate to stand on. Pinned language-by

### What the distribution contains, and what needs the git repository

MEASURED from the built wheel (`argus_agent-0.1.0-py3-none-any.whl`, 104 entries) and sdist
(`argus_agent-0.1.0.tar.gz`, 103 files), not inferred: `[tool.flit.module] name = "argus"`
MEASURED from the built wheel (`argus_agent-1.0.0-py3-none-any.whl`, 116 entries) and sdist
(`argus_agent-1.0.0.tar.gz`, 115 files), not inferred — ~~`argus_agent-0.1.0-…`, 104 entries /
103 files~~ struck, not deleted (§3.4): the filenames moved with the 1.0.0 bump and the counts
with Epic 20: `[tool.flit.module] name = "argus"`
packages **the `argus` Python package and nothing else** — which, since Story 12.7, includes
the command assets under `argus/assets/commands/`: `flit_core` walks the whole `argus/`
directory and ships every file in it, so a `.md` there reaches the wheel with **no**
Expand Down Expand Up @@ -284,7 +286,11 @@ to contradict each other (see the struck sentence under [Slash Commands](#-slash

> **Measured limitation, stated rather than discovered later — and now measured away.** On a
> freshly built wheel, with this repository removed from `sys.path` and one clean subprocess
> per module, **96 of the 96 shipped modules import**. None fail. (96, not 95, since
> per module, **108 of the 108 shipped modules import**. None fail. (108, not 96, since
> 2026-08-29: Epic 20 added twelve modules across three packages — `argus/parsers` (3,
> Story 20.1), `argus/remediation` (4, Story 20.2) and `argus/adapters/lsp` (5, Story 20.3).
> They IMPORT, which is all this sentence measures; none of the three is reachable from any
> entry point, so nothing an operator can invoke moved. 96, not 95, since
> 2026-08-25: Story 17.3 added `argus/detectors/assertion_strength.py`, which GRADES what
> each assertion in a flagged test span constrains and lands the successor vacuity
> predicate `S1` as code. It is ADVISORY and promotes nothing: no finding becomes
Expand Down
17 changes: 16 additions & 1 deletion _bmad-output/design-artifacts/ArgusAgent/E-PRD/.memlog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
topic: ArgusAgent PRD — FR16/FR4 verdict-contract amendment
updated: 2026-08-03T18:53
updated: 2026-08-29T08:35
---

- (event) Update intent opened: amend FR16 (verdict decision table) + FR4 (critical-subsystem eligibility) per sprint-change-proposal-2026-08-03 step 4 (contract gate)
Expand All @@ -11,3 +11,18 @@ updated: 2026-08-03T18:53
- (change) Applied: FR16 rewritten with binding ordered decision table (findings before coverage; row 4 = zero-findings unmet gate -> INSUFFICIENT_COVERAGE exit 3); FR4 gained heuristic-set eligibility predicate + operator-designation exemption + prefix exclusion; L400 vocabulary note widened; L140 Technical Success restatement realigned
- (change) Created addendum.md capturing downstream depth: options-considered matrix for the vocabulary decision, VERDICT_SCHEMA_VERSION 1->2 bump, touched modules, integrator migration note, CR-2 coverage-scope default release note
- (assumption) Assumed CR-3's 'clean-parsed zero-definition modules' exclusion applies to the heuristic critical set only, not to operator --critical-subsystem designations; proposal states operator designation keeps conservative behaviour but does not enumerate the zero-definition case
- (event) Update intent opened: promote FR38-FR40 from addendum.md into prd.md per sprint-change-proposal-2026-08-28; closes retro action AI-E20-3
- (decision) XAgent007 APPROVED promotion: FR38-FR40 move from addendum.md A2 into prd.md body, topically placed per the FR34-FR37 (2026-08-10b) precedent; addendum retains rationale only. Reason = downstream skills derive from prd.md, which had no FR38-40, no Post-V1 scope entry and no 2026-08-28 amendment
- (decision) XAgent007 APPROVED: FR38/FR39 recorded as library seams per the FR23/24/26/29 (2026-08-11, Story 10.5) precedent. MEASURED: zero importers of argus.remediation/argus.adapters/argus.parsers anywhere else in argus/, no argus/cli.py reference, no console-script entry point beyond argus.cli:main + the FR35 MCP alias; tests/test_post_v1_integration.py imports the packages directly (library-level, not E2E through the CLI)
- (decision) XAgent007 APPROVED: FR40 restated as DEFINITION EXTRACTION, not language coverage. MEASURED: argus/shared/source_languages.py already maps .js/.jsx/.mjs/.cjs/.ts/.tsx/.mts/.cts/.go/.java and is byte-unchanged by Epic 20 (last touched c5db6f3, 2026-08-13); tree-sitter grammars for all four already pinned at pyproject.toml:61-65. The 2026-08-28 draft's 'existing Python, C/C++, Ruby, Rust' baseline contradicts the 2026-08-10 amendment and is corrected struck-not-deleted
- (event) VERIFIED NOT A VIOLATION: argus/adapters/lsp/server.py imports socket but never binds/listens/accepts - it writes to a CALLER-SUPPLIED stream (isinstance(stream, socket.socket) at server.py:60). FR35's 'no network listener is opened and no port is bound' constraint and the argus.* NOT-IMPORTS fastapi isolation gate both hold; FR39 records the boundary rather than claiming a breach
- (event) FR40 MEASUREMENT SUPERSEDES THE APPROVED RESTATEMENT: argus/index/ast_index.py::_DEF_KIND_BY_NODE (byte-unchanged by Epic 20) ALREADY maps function_declaration/method_declaration/class_declaration/type_declaration, i.e. TS, JS, Go and Java already extracted definitions in V1 through the PRODUCTION indexer - which is precisely why DF-10-2-A named only C, C++, Ruby and Rust. argus/parsers/extended.py therefore adds neither language coverage NOR definition extraction to the audit path; it adds a parallel, unreachable parser API that duplicates the indexer and does NOT address the DF-10-2-A shortfall. Escalated to XAgent007 before writing FR40
- (decision) XAgent007 APPROVED: FR40 IS admitted to the capability contract, with the drafted text struck-not-deleted and the full FR29-style disposition recorded (already grounded AND already definition-extracted in V1; extended.py duplicates argus/index/ast_index.py; unreachable; does NOT address DF-10-2-A). Rejected keeping it out of the contract - admitting it preserves the trace that something was promised
- (event) HALT at TC-ArgusAgent-DOCS-001-35: the guard models a seam as DISCOVERED AFTER its FR exists, so it demands a >=60-char struck span plus the single hardcoded act _DISPOSITION_DATE=2026-08-11 / _DISPOSITION_STORY='Story 10.5'. FR38-FR40 are ADMITTED AND DISPOSED IN THE SAME ACT on 2026-08-28: FR38/FR39 have NO prior claim to strike, and none of the three can truthfully carry 10.5 attribution. Fabricating a struck sentence would manufacture a prior claim that never existed, which is the exact dishonesty this guard exists to prevent. DN-4 closes the disposition VOCABULARY (library-seam is an existing label, so DN-4 is satisfied) but nothing locks the date/story constants, whose comment states their purpose as attribution. Escalated to XAgent007 rather than resolved unilaterally
- (change) SUPERSESSION, recorded so entry 17 is not acted on: entry 17's approved 'restate FR40 as definition extraction' was OVERTAKEN by the entry-19 measurement and replaced by entry 20's disposition. FR40 as written claims NEITHER new language coverage NOR new extraction - it records a duplicate, unreachable parser API. Entry 17 stands as the decision that was taken at the time; entry 20 is the one in force
- (decision) XAgent007 APPROVED generalizing TC-ArgusAgent-DOCS-001-35 rather than reverting the promotion or leaving it red. _Delivery gains disposed_on/disposed_by/same_act, DEFAULTED to the 2026-08-11 / Story 10.5 constants so every pre-existing entry keeps its exact meaning; the >=60-char strike is now required only when the FR PREDATES its disposition, and a same-act entry must instead name 'library-seam' in its own FR text. Rationale = the constants encoded an assumption true of exactly one sweep, and the strike branch would have forced FR38/FR39 to invent a prior claim - the dishonesty the guard exists to catch. DN-4 satisfied: no new disposition label was invented
- (change) FILED DF-20-1-A (FR40 duplicates argus/index/ast_index.py, unreachable, does NOT close DF-10-2-A which stays OPEN), DF-20-2-A (FR38 remediation unreachable, FR29's fence), DF-20-3-A (FR39 LSP unreachable, plus the checked-and-clean socket/no-bind finding) in deferred-work.md. Ledger grepped first for DF-20-/FR38/FR39/FR40/remediation/lsp/parser: NO prior art. Also recorded that tests/test_post_v1_integration.py pins library behaviour, not reachability, and must not be cited as evidence of the opposite
- (decision) XAgent007 chose rubric-walker-only for the Finalize reviewer gate and SKIPPED the doc_standards polish pass. Reason for skipping polish = this PRD's voice is load-bearing and guard-checked (struck spans are measured by a >=60-char floor), so a general prose pass could trip TC-ArgusAgent-DOCS-001-35
- (event) PRD finalized. Reviewer gate: rubric walker, verdict STRONG, 0 critical / 0 high / 2 medium / 1 low; both mediums RESOLVED (prd.md:447 no-language-server claim cross-referenced to FR39; FR38/FR39 rooted as the V2 developer-surface item recorded at the destination, FR40 explicitly NOT rooted). Low ACCEPTED without change. Retro and CHANGELOG.md corrected struck-not-deleted so neither reads as shipped. review-rubric.md MOVED out of E-PRD/ to prd-review-rubric-2026-08-29.md: E-PRD/*.md is a guarded specification glob and a review document is not a specification. Polish SKIPPED by operator choice. One PRE-EXISTING failure left untouched and reported: architecture.md fails TC-ArgusAgent-DOCS-001-24 on two Epic 20 lines - AI-E20-3 territory, zero E-PRD sites among the violations
- (change) AI-E20-3 DISCHARGED: architecture.md section J corrected. (1) A reachability banner opens the section, stating that J certifies module PLACEMENT ONLY and that none of J1/J2/J3 is reachable, citing TC-ArgusAgent-DOCS-001-34 as the proof and DF-20-1-A/-2-A/-3-A as the filings. (2) J1 and the FR40 module-placement bullet now record that multi-language AST grounding is DELIVERED IN V1 and that extended.py is an unreachable duplicate of argus/index/ast_index.py which does NOT close DF-10-2-A. The guard's only escape hatch is the literal delivered-in-V1 wording, so quieting it required writing the true sentence. NOTE ON UNIT BOUNDARIES: the marker had to move INSIDE the flagged sentence - a correction placed after the terminal period is a separate scan unit and does not clear the finding. TC-ArgusAgent-DOCS-001-24 now GREEN
- (event) VERIFIED GREEN on Windows: 1,845 tests across 141 files, pytest exit 0, zero failures; mypy argus/ clean over 108 source files; bandit -r argus --severity-level medium (CI's exact command) exit 0. NOT the full 4-step gate - the WSL Ubuntu matrix was not run this session
30 changes: 30 additions & 0 deletions _bmad-output/design-artifacts/ArgusAgent/E-PRD/addendum.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,33 @@ block" was in FR16 from the original draft; what shipped was a decision table wh
`otherwise` row violated it. Journey 3 already specified "`INSUFFICIENT_COVERAGE` routing
to human review (never a silent pass *or a false block*)" — the amended table is the first
version that actually delivers the second half of that clause.

---

## A2 — Post-V1 Capabilities: why FR38–FR40 read as they do (2026-08-28)

**Change signal:** [sprint-change-proposal-2026-08-28.md](../sprint-change-proposal-2026-08-28.md)
**Approved by:** XAgent007 — scope 2026-08-28; promotion and dispositions 2026-08-29.

**The FR text is not in this file.** FR38, FR39 and FR40 live in `prd.md` §Functional Requirements, topically placed. What follows is only the reasoning behind that placement and their dispositions.

### Why they moved out of the addendum

The 2026-08-28 proposal (§4) routed FR38–FR40 here. That is the wrong destination for a functional requirement: the addendum carries downstream depth — rejected alternatives, mechanism decisions, options matrices — while the **binding capability contract is `prd.md`**, whose own preamble states that a capability not listed there will not exist. Left here, three *built* capabilities would have been invisible to every downstream skill that reads `prd.md` alone, and the PRD would have carried no record that Epic 20 happened at all. The 2026-08-10b amendment set the precedent: FR34–FR37 went into the PRD body, and only their rationale stayed behind.

### Why all three are disposed `library-seam`

Measured 2026-08-29, not inferred: nothing outside `argus/remediation`, `argus/adapters` and `argus/parsers` imports any of them; `argus/cli.py` names none of them; `[project.scripts]` gained no entry point. `tests/test_post_v1_integration.py` — the story's "E2E" suite — reaches the packages by direct import, which pins library behaviour rather than an invocable path. Story 10.5 met this exact shape in FR23/FR24/FR26/FR29, and its ruling governs here: the sharpest case is an FR whose text names an operator when no operator can reach the capability.

### Options considered for FR40, and why the narrow wording won

| Option | Outcome |
|---|---|
| Keep the drafted wording | **Rejected** — contradicts both the 2026-08-10 amendment and the on-disk baseline. |
| Restate as "adds definition extraction" | **Rejected on measurement** — `argus/index/ast_index.py::_DEF_KIND_BY_NODE` already carries the TS/JS, Go and Java vocabulary, byte-unchanged by Epic 20. |
| Keep FR40 out of the contract entirely | **Rejected** — an unrecorded promise leaves no trace that anything was committed; the same under-counting Story 10.5 refused. |
| **Admit it with the full disposition** | **Chosen** — records what exists, that it duplicates the indexer, that it is unreachable, and that `DF-10-2-A` is still open. |

### What was deliberately not done

No code shipped, no schema version moved, `argus/**` is byte-unchanged, and the ≥80% precision gate is untouched. The duplication between `argus/parsers/extended.py` and `argus/index/ast_index.py` is **recorded, not resolved**: wiring it in and removing it are both still open, and neither was decided under a PRD amendment.
Loading
Loading