@antoneeo/mkt-agentic-sdlc-skill 0.26.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +43 -0
- package/README.md +41 -13
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/scripts/init.js +6 -6
- package/skills/mkt-agentic-sdlc/ENFORCEMENT.md +3 -3
- package/skills/mkt-agentic-sdlc/SKILL.md +2 -2
- package/skills/mkt-agentic-sdlc/docs_site/app.js +7 -1
- package/skills/mkt-agentic-sdlc/docs_site/strings.js +9 -0
- package/skills/mkt-agentic-sdlc/docs_site/style.css +2 -0
- package/skills/mkt-agentic-sdlc/guides.md +8 -0
- package/skills/mkt-agentic-sdlc/review.md +37 -1
- package/skills/mkt-agentic-sdlc/scripts/docs_site.py +17 -3
- package/skills/mkt-agentic-sdlc/scripts/knowledge.py +925 -33
- package/skills/mkt-agentic-sdlc/scripts/mkt_check.py +2 -1
- package/skills/mkt-agentic-sdlc/scripts/sdlc_core.py +609 -29
- package/skills/mkt-agentic-sdlc/vision.md +308 -308
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,48 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.28.0] - 2026-10-31
|
|
4
|
+
|
|
5
|
+
### What's new
|
|
6
|
+
|
|
7
|
+
**One approval, not two.** The other skills of the family now have the owner approve a design before the work starts. In marketing that approval already exists: you approve the strategy before any tactic. It now counts as that approval, so the agent asks you nothing more.
|
|
8
|
+
|
|
9
|
+
**The npm page tells you what is new.** This section, at the top of the package page, now summarizes each version for the people who install it.
|
|
10
|
+
|
|
11
|
+
**From 0.27.0, published without notes:**
|
|
12
|
+
- **The process checks can no longer be bypassed by accident.** Quoting a work level inside a sentence no longer counts as declaring it, and protected parts of the project stay protected when the agent changes folder.
|
|
13
|
+
- **You know what the project memory has not read yet.** The agent can tell how much of the project it has never examined (automatically in projects with a corpus, on request otherwise).
|
|
14
|
+
|
|
15
|
+
#### What to do
|
|
16
|
+
|
|
17
|
+
**1. Update (everyone).** The changes arrive only with the update.
|
|
18
|
+
1. Run `npm install -g @antoneeo/mkt-agentic-sdlc-skill@latest`, then `mkt-sdlc-install-skill`.
|
|
19
|
+
2. Close and reopen your agent sessions: the new version loads only at startup.
|
|
20
|
+
|
|
21
|
+
To check: `npm ls -g @antoneeo/mkt-agentic-sdlc-skill` shows 0.28.0.
|
|
22
|
+
|
|
23
|
+
**2. Protected folders in a repository with several docs folders (only if you use them; from 0.27.0).**
|
|
24
|
+
- **This concerns you if** your agent settings contain `gate --hook --protected` and the repository has more than one docs folder (`mkt_docs/` or `ai_docs/`), for example a package with its own.
|
|
25
|
+
- **Why:** protected paths are now read from the docs folder nearest to the edited file. A path written from the repository root, such as `packages/api/src/auth`, no longer matches the files inside `packages/api`, so the agent could change them without an analysis.
|
|
26
|
+
- **Steps:** rewrite those paths from the package: `packages/api/src/auth` becomes `src/auth`. Note that `src/auth` then protects the folder with that name in every project that has its own docs folder.
|
|
27
|
+
- **To check:** in a session with no open analysis, ask the agent for a small change to a protected file. It must be refused.
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
- The client's approval of the strategy (phase 6 USER GATE) is now named as the owner's design approval of the shared `review.md`: no second question is added, and the lens's own unattended path applies. The shared `review.md` carries the rule the other lenses follow (F-087).
|
|
31
|
+
- The shared validator: `validate` notes an L3 ANALYSIS in implementation, started on or after 2026-10-31, whose request record holds no entry whose label begins `design approved`. It is a `[note]`: `--strict` exits as before. The `gate` refusal message adds that at L3 the ANALYSIS goes `IN_PROGRESS` only after the owner's design approval; its exit codes are unchanged (F-087).
|
|
32
|
+
- The package's npm page (its README) gains a "What's new in <version>" section right after the introduction, written for the people who install the package and linking the full CHANGELOG. It appears from the first version that carries one; each version's notes are the `### What's new` at the top of its CHANGELOG section (F-070). The "Shared project memory" section moves from the top of the page to just after the features, unchanged.
|
|
33
|
+
|
|
34
|
+
## [0.27.0] - 2026-10-27
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
- Shared knowledge layer (F-084, kb CHANGELOG): `inventory <path>` and orient's upper bound of never-examined project files reach this lens; `validate`/`check` refuse a malformed `audit/INVENTORY_exclusions.md` row and the new `DECLARED`/`DIVERGES` claim rules; the docs site renders them. `sdlc_core.skip_dir` is extracted from `iter_files`, behaviour unchanged.
|
|
38
|
+
- `constraints --unit <id>` and `constraints --file <path>` (shared core): the constraints an ANALYSIS states in extractable form, each with its line, ending with the sections they could not extract.
|
|
39
|
+
- `benefit` and the docs site recognize a REVIEW_LOG row with tier `post-merge` (written by the code lens: the owner's report of a wrong behaviour in a merged change): `benefit` keeps it out of every review figure, the docs site shows it as "defect reported after merge". `review.md`: a reviewer derives callers and behaviours before comparing with the constraint view.
|
|
40
|
+
- `guides.md`: a code guide may carry a `## Preservation constraints` section copied from a closed unit; it survives regeneration. Nothing else changes in this lens: `validate` adds no note.
|
|
41
|
+
|
|
42
|
+
### Fixed
|
|
43
|
+
- Shared claim checks (`check`): a `RULING` row on a note that names a foreign origin (`imported_from:`) is refused — relabelling an imported row is not ratifying it; the message for a row superseded by an `IMPORTED` one names the ratification act (F-083).
|
|
44
|
+
- Guide-verdict check (`verdict --hook`, shared core): a level quoted inside a sentence (`Level: L1` in prose) no longer counts as a declaration: only a line that opens with the level word does, the rule the constraint recall already uses (level 1 alone, `L1` or `E1`; levels 2 and 3 with `router` on the same line). The check now judges the project, and its docs-root name, that holds the edited file, not the one around the session's working directory; after a `cd` out of the project it let every edit through. A router verdict follows the same rule: only a line that opens with `router` or declares the level with it counts, never `router: no match` quoted in a sentence; `Level: Spike · router: …` and markdown openers (`##`, `1.`, `•`) count. A quote that itself opens a line (blockquote, code fence) still counts. The protected-path gate (`gate --hook`, `gate --file`) also judges the edited file's project, falls back to the session's project when no docs root sits above the file, and stays silent instead of exiting with an error when two docs roots sit side by side. Its `--protected` prefixes are relative to the nearest docs root above the edited file: with nested docs roots (a monorepo package with its own `ai_docs/`, or a docs folder inside a protected path) rewrite them relative to that root, or the path is no longer protected.
|
|
45
|
+
|
|
3
46
|
## [0.26.0] - 2026-10-23
|
|
4
47
|
|
|
5
48
|
### Changed
|
package/README.md
CHANGED
|
@@ -1,22 +1,35 @@
|
|
|
1
1
|
# Marketing Agentic SDLC Skill
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Evidence-First marketing planning protocol for AI coding agents (Claude Code, Gemini CLI, Google Antigravity, Codex). The sibling of [`@antoneeo/agentic-sdlc-skill`](https://www.npmjs.com/package/@antoneeo/agentic-sdlc-skill), transplanted from software engineering to marketing strategy.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
`recall "onboarding"` finds related metadata across domains; optional
|
|
9
|
-
`topics: [onboarding]` links documents by subject. Read the originals for authority,
|
|
10
|
-
status and evidence: discovery is not approval or proof of implementation.
|
|
5
|
+
<!-- whats-new:begin -->
|
|
6
|
+
<!-- generated by scripts/whats_new.js from distributions/mkt-agentic-sdlc/CHANGELOG.md: edit the CHANGELOG, then run node scripts/whats_new.js --write -->
|
|
7
|
+
## What's new in 0.28.0
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
watcher. Existing projects acquire the catalog on their next `index`; `recall`
|
|
14
|
-
also sees live metadata. The KB lens remains the specialist for ingestion and
|
|
15
|
-
taxonomy. Marketing retains its numerical validators. See the skill's `memory.md`.
|
|
16
|
-
Vendoring requires all three files: the entry point, `sdlc_core.py`, `knowledge.py`.
|
|
9
|
+
**One approval, not two.** The other skills of the family now have the owner approve a design before the work starts. In marketing that approval already exists: you approve the strategy before any tactic. It now counts as that approval, so the agent asks you nothing more.
|
|
17
10
|
|
|
11
|
+
**The npm page tells you what is new.** This section, at the top of the package page, now summarizes each version for the people who install it.
|
|
18
12
|
|
|
19
|
-
|
|
13
|
+
**From 0.27.0, published without notes:**
|
|
14
|
+
- **The process checks can no longer be bypassed by accident.** Quoting a work level inside a sentence no longer counts as declaring it, and protected parts of the project stay protected when the agent changes folder.
|
|
15
|
+
- **You know what the project memory has not read yet.** The agent can tell how much of the project it has never examined (automatically in projects with a corpus, on request otherwise).
|
|
16
|
+
|
|
17
|
+
#### What to do
|
|
18
|
+
|
|
19
|
+
**1. Update (everyone).** The changes arrive only with the update.
|
|
20
|
+
1. Run `npm install -g @antoneeo/mkt-agentic-sdlc-skill@latest`, then `mkt-sdlc-install-skill`.
|
|
21
|
+
2. Close and reopen your agent sessions: the new version loads only at startup.
|
|
22
|
+
|
|
23
|
+
To check: `npm ls -g @antoneeo/mkt-agentic-sdlc-skill` shows 0.28.0.
|
|
24
|
+
|
|
25
|
+
**2. Protected folders in a repository with several docs folders (only if you use them; from 0.27.0).**
|
|
26
|
+
- **This concerns you if** your agent settings contain `gate --hook --protected` and the repository has more than one docs folder (`mkt_docs/` or `ai_docs/`), for example a package with its own.
|
|
27
|
+
- **Why:** protected paths are now read from the docs folder nearest to the edited file. A path written from the repository root, such as `packages/api/src/auth`, no longer matches the files inside `packages/api`, so the agent could change them without an analysis.
|
|
28
|
+
- **Steps:** rewrite those paths from the package: `packages/api/src/auth` becomes `src/auth`. Note that `src/auth` then protects the folder with that name in every project that has its own docs folder.
|
|
29
|
+
- **To check:** in a session with no open analysis, ask the agent for a small change to a protected file. It must be refused.
|
|
30
|
+
|
|
31
|
+
Full history: [CHANGELOG](https://github.com/Antoneeo/agentic-sdlc-skill/blob/main/distributions/mkt-agentic-sdlc/CHANGELOG.md)
|
|
32
|
+
<!-- whats-new:end -->
|
|
20
33
|
|
|
21
34
|
## What it does
|
|
22
35
|
|
|
@@ -31,6 +44,21 @@ The **docs site** (`scripts/docs_site.py --root <project> [--open] [--zip <file>
|
|
|
31
44
|
|
|
32
45
|
The agent asks the user only for facts the user uniquely owns (product, price, budget, capacity); everything else — market sizing, competitor analysis, channel benchmarks — is derived from real web research.
|
|
33
46
|
|
|
47
|
+
## Shared project memory
|
|
48
|
+
|
|
49
|
+
All four lenses include project memory by default; install the lens you need,
|
|
50
|
+
not a second skill just for recall. `index` registers guides, decisions and plans
|
|
51
|
+
in the docs root's `memory/INDEX.md`, linking originals without copying them.
|
|
52
|
+
`recall "onboarding"` finds related metadata across domains; optional
|
|
53
|
+
`topics: [onboarding]` links documents by subject. Read the originals for authority,
|
|
54
|
+
status and evidence: discovery is not approval or proof of implementation.
|
|
55
|
+
|
|
56
|
+
Registration happens at `index`/documentation closure, not through a background
|
|
57
|
+
watcher. Existing projects acquire the catalog on their next `index`; `recall`
|
|
58
|
+
also sees live metadata. The KB lens remains the specialist for ingestion and
|
|
59
|
+
taxonomy. Marketing retains its numerical validators. See the skill's `memory.md`.
|
|
60
|
+
Vendoring requires all three files: the entry point, `sdlc_core.py`, `knowledge.py`.
|
|
61
|
+
|
|
34
62
|
## Install
|
|
35
63
|
|
|
36
64
|
```bash
|
package/gemini-extension.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mkt-agentic-sdlc",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.0",
|
|
4
4
|
"description": "Evidence-First marketing planning protocol with engagement triage, SOSTAC workflow, evidence ledger and optional devPNT integration.",
|
|
5
5
|
"author": "Antonio Pinto (https://github.com/Antoneeo)"
|
|
6
6
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antoneeo/mkt-agentic-sdlc-skill",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.0",
|
|
4
4
|
"description": "Evidence-First marketing planning protocol for Claude Code, Gemini CLI, Google Antigravity and Codex: engagement triage, SOSTAC workflow, evidence ledger, mechanical validator and optional devPNT integration.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|
package/scripts/init.js
CHANGED
|
@@ -194,16 +194,16 @@ in the skill's \`routing.md\`: it decides which lens's method and validation rul
|
|
|
194
194
|
that unit. L1 never reaches it. Never refer to a document whose meaning differs by lens
|
|
195
195
|
("threat model", "vision", \`principles.md\`, \`handoff.md\`) by its bare name.
|
|
196
196
|
|
|
197
|
-
Select the owning lens by the unit's purpose, then apply only its risk scale.
|
|
198
|
-
The project's always-on pointer stays intact: consult the selected skill rather than
|
|
199
|
-
merging multiple mandatory ladders. All lenses already carry shared project memory
|
|
200
|
-
(\`memory.md\`); another installation is not needed for cross-domain recall.
|
|
197
|
+
Select the owning lens by the unit's purpose, then apply only its risk scale.
|
|
198
|
+
The project's always-on pointer stays intact: consult the selected skill rather than
|
|
199
|
+
merging multiple mandatory ladders. All lenses already carry shared project memory
|
|
200
|
+
(\`memory.md\`); another installation is not needed for cross-domain recall.
|
|
201
201
|
This file is NOT auto-loaded by any client: it is a note for you, deliberately additive.
|
|
202
|
-
Delete this note once the routing pointer is integrated.
|
|
202
|
+
Delete this note once the routing pointer is integrated.
|
|
203
203
|
`, 'multi-lens routing note');
|
|
204
204
|
if (wrote && protocolPreexisting) {
|
|
205
205
|
console.log(' ⚠️ A protocol pointer already existed and was NOT overwritten.');
|
|
206
|
-
console.log(' Integrate the routing pointer from AGENTIC_MULTI_LENS.md; keep one risk scale per unit.');
|
|
206
|
+
console.log(' Integrate the routing pointer from AGENTIC_MULTI_LENS.md; keep one risk scale per unit.');
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
209
|
|
|
@@ -54,15 +54,15 @@ Semantics: exit code 2 + message on stderr ⇒ the write is blocked and the mess
|
|
|
54
54
|
|
|
55
55
|
**Usage warnings:**
|
|
56
56
|
- The gate is deliberately coarse: applied to all of `src/` it would also block the legitimate L1/L2 tasks foreseen by the Triage. Use it **only on security-critical directories** (`--protected "src/auth;src/crypto"`), where "never without analysis" is the desired policy.
|
|
57
|
-
- The paths in `--protected` are prefixes relative to the project
|
|
57
|
+
- The paths in `--protected` are prefixes relative to the root of the project the hook judges (below), separated by `;`. With nested docs roots (a monorepo whose package has its own), that is the nearest one above the edited file: write the prefixes relative to it.
|
|
58
58
|
- `ai_docs/`, `tests/` and `test/` are always excluded from blocking.
|
|
59
|
-
- The hook
|
|
59
|
+
- The hook judges the project, and the docs root, holding the edited file: the session's working directory can move with a `cd`, so it is never the reference. With no docs root above the file, it is the session's own project, as before. `--root <path>` overrides it; `gate --file` resolves the same way, and two docs roots side by side leave the gate silent.
|
|
60
60
|
- **Hybrid/devPNT projects**: add `--hybrid` to the gate command. Governed designs live in the devPNT DB, so the gate also unlocks when an approved E-TDD shadow (`ai_docs/solutions/SHADOW_*tdd*.md`, exported before implementation — see `hybrid.md` §Ownership matrix) is present. Without the flag the gate would block legitimate governed work. The flag is deliberately explicit: never auto-detected.
|
|
61
61
|
|
|
62
62
|
### Verdict check: `verdict` (PreToolUse -- manual for this lens)
|
|
63
63
|
|
|
64
64
|
`mkt_check.py verdict --hook` refuses an Edit, Write, MultiEdit or NotebookEdit when the
|
|
65
|
-
session transcript shows no guide-router verdict (`router: …`, or a level-1 declaration)
|
|
65
|
+
session transcript shows no guide-router verdict (a line that opens with `router: …` or with the level, `Level: L2 · router: …`, `Level: Spike · router: …`; or one that opens with a level-1 declaration)
|
|
66
66
|
or a guide the verdict names was never read; it is silent in projects without guides and
|
|
67
67
|
whenever it cannot tell. The code package (`agentic-sdlc`) wires it machine-wide on
|
|
68
68
|
Claude Code; this package does not. To wire it by hand, add a `PreToolUse` entry with
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mkt-agentic-sdlc
|
|
3
|
-
version: 0.
|
|
3
|
+
version: 0.28.0
|
|
4
4
|
description: Evidence-First marketing planning protocol with engagement triage, SOSTAC workflow, evidence ledger, adversarial CMO review, a complete Standalone mode and optional symbiosis with devPNT. Use for marketing plans, go-to-market strategy, campaign planning and market research.
|
|
5
5
|
author: Antonio Pinto (https://github.com/Antoneeo)
|
|
6
6
|
copyright: (c) 2026 Antonio Pinto
|
|
@@ -161,7 +161,7 @@ Deliverable language: ask for (or infer) the target market's language in Discove
|
|
|
161
161
|
- **Design review gate:** the strategy is reviewed by somebody other than its author before any tactic is executed — a subagent with fresh context, or a declared self-pass when no higher rung is usable — a permission-gated rung is asked about, never silently skipped (`review.md`). Follow `review.md`; log the outcome in `audit/reviews/REVIEW_LOG.md` under the docs root. A strategy reviewed only by the person who wrote it is not reviewed.
|
|
162
162
|
- Draft `STRATEGY.md`: segmentation, targeting choice with rationale, positioning (Dunford components + statement), messaging house.
|
|
163
163
|
- **Adversarial review** (`review.md`) before the user sees it. Fix or answer every finding.
|
|
164
|
-
- The user approves the strategy. Hybrid: propose as governed doc, user accepts in devPNT.
|
|
164
|
+
- The user approves the strategy. This is the owner's design approval of `review.md` §When a review is due, so no second question follows. Hybrid: propose as governed doc, user accepts in devPNT.
|
|
165
165
|
|
|
166
166
|
### 7. Tactics — **VALIDATOR GATE**
|
|
167
167
|
- Run elicitation **Wave 3** (execution capacity: who writes, who runs ads, tooling, sales follow-up).
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
var D = null; // documents, loaded on first use
|
|
13
13
|
var K = null; // knowledge base, loaded on first use
|
|
14
14
|
var app = document.getElementById("app");
|
|
15
|
-
var ORIGINS = ["given", "elicited", "derived", "ruling", "imported"];
|
|
15
|
+
var ORIGINS = ["given", "elicited", "derived", "ruling", "imported", "declared"];
|
|
16
16
|
|
|
17
17
|
// ------------------------------------------------------------- helpers
|
|
18
18
|
|
|
@@ -483,6 +483,7 @@
|
|
|
483
483
|
if (f.statement) marks.push(el("span", { "class": "tag statement", title: t("statement_notice"), text: t("statement_mark") }));
|
|
484
484
|
if (f.state === "superseded") marks.push(el("span", { "class": "tag replaced", title: t("state_superseded_why"), text: t("state_superseded") }));
|
|
485
485
|
if (f.state === "contested") marks.push(el("span", { "class": "tag conflict", title: t("state_contested_why"), text: t("state_contested") }));
|
|
486
|
+
if (f.state === "diverges") marks.push(el("span", { "class": "tag conflict", title: t("state_diverges_why"), text: t("state_diverges") }));
|
|
486
487
|
if (opts && opts.topic) marks.push(link("#/topic/" + encodeURIComponent(f.topic), f.topic, "chip"));
|
|
487
488
|
return el("li", { "class": "fact" + (f.state === "superseded" ? " replaced" : ""), onclick: function () { location.hash = "#/fact/" + encodeURIComponent(id); } },
|
|
488
489
|
el("span", { "class": "dot bg-" + oc }),
|
|
@@ -597,6 +598,11 @@
|
|
|
597
598
|
el("p", { "class": "why-line", text: t("state_contested_why") }),
|
|
598
599
|
el("ul", { "class": "facts" }, (f.with || []).map(function (s) { return factLine(s, { topic: true }); })));
|
|
599
600
|
}
|
|
601
|
+
if (f.state === "diverges") {
|
|
602
|
+
parts.push(el("h3", null, el("span", { "class": "tag conflict", text: t("state_diverges") }), " ", t("fact_diverges_from")),
|
|
603
|
+
el("p", { "class": "why-line", text: t("state_diverges_why") }),
|
|
604
|
+
el("ul", { "class": "facts" }, (f.diverges_from || []).map(function (s) { return factLine(s, { topic: true }); })));
|
|
605
|
+
}
|
|
600
606
|
if (f.grounds) {
|
|
601
607
|
parts.push(el("h3", { text: t("fact_rests_on") }),
|
|
602
608
|
el("p", { "class": "why-line", text: t("ground_class_" + f.ground_class) }),
|
|
@@ -56,7 +56,9 @@ window.DOCS_SITE_STRINGS = {
|
|
|
56
56
|
event_request: "request record",
|
|
57
57
|
event_note: "note",
|
|
58
58
|
event_source: "source document received",
|
|
59
|
+
event_sent: "document sent",
|
|
59
60
|
event_review: "review",
|
|
61
|
+
event_defect: "defect reported after merge",
|
|
60
62
|
event_decision: "decision record",
|
|
61
63
|
event_project_note: "project note",
|
|
62
64
|
event_spike: "exploration outcome",
|
|
@@ -231,6 +233,8 @@ window.DOCS_SITE_STRINGS = {
|
|
|
231
233
|
origin_ruling_why: "Taken to settle a conflict.",
|
|
232
234
|
origin_imported: "from another knowledge base",
|
|
233
235
|
origin_imported_why: "Brought in from another knowledge base, where its own sources are.",
|
|
236
|
+
origin_declared: "declared by this project",
|
|
237
|
+
origin_declared_why: "What this project told a recipient, on the day it was sent: a statement of ours, not a fact about the product.",
|
|
234
238
|
origin_other: "origin as written: {v}",
|
|
235
239
|
origin_other_why: "An origin this site does not know.",
|
|
236
240
|
|
|
@@ -239,6 +243,8 @@ window.DOCS_SITE_STRINGS = {
|
|
|
239
243
|
state_superseded_why: "A newer fact takes its place.",
|
|
240
244
|
state_contested: "in conflict",
|
|
241
245
|
state_contested_why: "Facts that disagree, not yet settled.",
|
|
246
|
+
state_diverges: "diverges",
|
|
247
|
+
state_diverges_why: "What we declared contradicts what the project decided. It is corrected by a new send, or the decision changes.",
|
|
242
248
|
|
|
243
249
|
statement_mark: "statement",
|
|
244
250
|
statement_prefix: "[statement] {text}",
|
|
@@ -254,6 +260,7 @@ window.DOCS_SITE_STRINGS = {
|
|
|
254
260
|
fact_replaced_by: "Replaced by",
|
|
255
261
|
fact_current_at_end: "Current fact at the end of each chain",
|
|
256
262
|
fact_in_conflict_with: "In conflict with",
|
|
263
|
+
fact_diverges_from: "Diverges from",
|
|
257
264
|
fact_rests_on: "What it rests on",
|
|
258
265
|
fact_untraced: "This part could not be traced.",
|
|
259
266
|
fact_sources: "Sources",
|
|
@@ -266,6 +273,7 @@ window.DOCS_SITE_STRINGS = {
|
|
|
266
273
|
fact_unknown: "This fact is not in this knowledge base.",
|
|
267
274
|
|
|
268
275
|
ground_document: "a document",
|
|
276
|
+
ground_declared: "a document this project sent",
|
|
269
277
|
ground_statement: "a person's statement",
|
|
270
278
|
ground_decision: "a decision",
|
|
271
279
|
ground_kb: "another knowledge base",
|
|
@@ -273,6 +281,7 @@ window.DOCS_SITE_STRINGS = {
|
|
|
273
281
|
ground_class_statement: "Rests, at least in part, on a person's statement.",
|
|
274
282
|
ground_class_untraceable: "Part of what it rests on could not be traced.",
|
|
275
283
|
ground_class_imported: "Rests on another knowledge base.",
|
|
284
|
+
ground_class_declared: "Rests on our own declaration to a recipient, not on evidence.",
|
|
276
285
|
ground_class_documents: "Rests on documents or decisions only.",
|
|
277
286
|
|
|
278
287
|
chain_loop: "The chain of replacements loops back to {id}: it stops here.",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
--o-derived: #a99be0;
|
|
19
19
|
--o-ruling: #7fa7e6;
|
|
20
20
|
--o-imported: #9cc96b;
|
|
21
|
+
--o-declared: #d98fb0;
|
|
21
22
|
--conflict: #e0605a;
|
|
22
23
|
--display: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Charter, Georgia, serif;
|
|
23
24
|
--body: "Segoe UI Variable Text", "Avenir Next", Avenir, "Gill Sans Nova", "Gill Sans", "Trebuchet MS", sans-serif;
|
|
@@ -179,6 +180,7 @@ a.factid code { color: var(--link); }
|
|
|
179
180
|
.o-derived { color: var(--o-derived); } .bg-derived { background: var(--o-derived); }
|
|
180
181
|
.o-ruling { color: var(--o-ruling); } .bg-ruling { background: var(--o-ruling); }
|
|
181
182
|
.o-imported { color: var(--o-imported); } .bg-imported { background: var(--o-imported); }
|
|
183
|
+
.o-declared { color: var(--o-declared); } .bg-declared { background: var(--o-declared); }
|
|
182
184
|
.o-other { color: var(--paper-3); } .bg-other { background: var(--paper-3); }
|
|
183
185
|
|
|
184
186
|
.panel {
|
|
@@ -262,6 +262,12 @@ in the snapshot, never to your assumption about what the code does.
|
|
|
262
262
|
(source-anchored), not an elaborated version of it.
|
|
263
263
|
- When in doubt about whether something is "supported" by the source, treat it
|
|
264
264
|
as not covered rather than stretching the marker to fit.
|
|
265
|
+
- **Declared exception: `## Preservation constraints`.** A code guide may carry
|
|
266
|
+
this section, copied at an L3 closure from the ANALYSIS's table (code lens,
|
|
267
|
+
`SKILL.md` Phase 5). The section's marker cites each row it holds as
|
|
268
|
+
`[source: solutions/ANALYSIS_<name>.md#P<n>]` instead of a snapshot anchor: each
|
|
269
|
+
row records what the code must keep doing, as that unit enumerated and probed it,
|
|
270
|
+
not an excerpt of the code.
|
|
265
271
|
|
|
266
272
|
## 4. Ingestion bound (T9)
|
|
267
273
|
|
|
@@ -293,5 +299,7 @@ state it explicitly when handing off a newly created guide.
|
|
|
293
299
|
closure (docs travel with the code); when you merely READ one, check it against
|
|
294
300
|
the code before trusting it. Too large to absorb → mark it `SUPERSEDED` rather
|
|
295
301
|
than leave a confident-wrong map badged CURRENT, which is worse than none.
|
|
302
|
+
- **A regenerated guide keeps `## Preservation constraints` unchanged**: the
|
|
303
|
+
section does not come from the snapshot (§3), so regeneration carries it over.
|
|
296
304
|
- **Agent-global KB guides** use the same pipeline and validator via
|
|
297
305
|
`--root ~/.agentic-sdlc`; freshness via the same `stale` engine.
|
|
@@ -187,7 +187,10 @@ can block forever gets removed. **Log one row per completed review, PASS or FAIL
|
|
|
187
187
|
logging only passes would erase exactly that evidence. The row goes in
|
|
188
188
|
`ai_docs/audit/reviews/REVIEW_LOG.md` (create it if absent — `templates.md`):
|
|
189
189
|
`| date | doc_key | tier | model | reviewer | findings_raised | findings_real | verdict | revise_rounds |`,
|
|
190
|
-
with `tier` = `design` or `closure` in Standalone.
|
|
190
|
+
with `tier` = `design` or `closure` in Standalone. In the code lens, a wrong behaviour
|
|
191
|
+
the owner reports in a merged L3 change is one row too, tier `post-merge`, `model`
|
|
192
|
+
`none (owner report)`, reviewer `owner`, the owner quoted in the notes: a defect
|
|
193
|
+
record, not a review, so `benefit` keeps it out of every review figure. **`model` records the capability
|
|
191
194
|
tier that actually ran** — `deep`, `light`, `economy`, `single (client exposes no
|
|
192
195
|
choice)`, `below floor: <reason>`, or `none (not due)` on a NOT DUE row — never a provider name in doctrine (a project
|
|
193
196
|
may of course write its own model names in its own log). Without it the floor above
|
|
@@ -195,6 +198,34 @@ is a belief: the row would say a gate ran and never whether it could do its job,
|
|
|
195
198
|
the correlation with `revise_rounds` and `findings_real` — the only evidence the
|
|
196
199
|
policy pays — could not be drawn.
|
|
197
200
|
|
|
201
|
+
**The owner approves the design before the work starts (L3).** The reviewer judges
|
|
202
|
+
whether the design holds and serves the Vision; only the owner can say whether it is
|
|
203
|
+
what they meant beyond what the Vision wrote, and an intent error costs least before
|
|
204
|
+
the work exists. So the final design PASS — final once any scoped re-review it owed
|
|
205
|
+
has passed (§Review-driven corrections) — does not start the work: the agent
|
|
206
|
+
presents the design and asks the owner whether to proceed, in the form
|
|
207
|
+
`elicitation.md` §The form of a question gives a reserved approval. The presentation
|
|
208
|
+
is a short summary — what the change does (the Functional Spec, or the lens's
|
|
209
|
+
equivalent), for whom and through which surfaces (use cases, contract), what it
|
|
210
|
+
touches (Impact), the threats and their mitigations, the review's verdict with any
|
|
211
|
+
open findings — and the path of the full design. At the round cap, the hand-over the
|
|
212
|
+
cap prescribes, followed by this one question, takes the place of the form, and the
|
|
213
|
+
owner's answer settles both. An approval is recorded verbatim in the request record
|
|
214
|
+
under a label that begins `design approved`; a no or a correction takes its own
|
|
215
|
+
label, and the design goes back — where the revision changes what the review judged,
|
|
216
|
+
moment 1 runs again on that part first (the delta rule above). Only after the
|
|
217
|
+
approval does the ANALYSIS go `PLANNED` → `IN_PROGRESS` and the work start: code,
|
|
218
|
+
drafting or production, by lens. An instruction given before the design was shown
|
|
219
|
+
("carry on", "do the whole unit") does not approve it. Where a lens's own phases
|
|
220
|
+
already have the owner approve the design — the marketing lens's strategy USER GATE
|
|
221
|
+
— that gate is this approval, never a second question, and the lens's own unattended
|
|
222
|
+
path applies. Otherwise, unattended, the unit is `BLOCKED on the user`
|
|
223
|
+
(`elicitation.md` Unattended path), never approved by assumption; a late arrival
|
|
224
|
+
(moment 1b) asks before any further work. Hybrid: the owner's approval of the
|
|
225
|
+
`E-ISP`/`E-TDD` proposal in devPNT, under devPNT's own authorization rules, is this
|
|
226
|
+
approval. In Standalone, `validate` notes an L3 ANALYSIS in implementation, started
|
|
227
|
+
on or after 2026-10-31, whose request record holds no `design approved` entry.
|
|
228
|
+
|
|
198
229
|
**One schema for both modes**, meaning one required CORE plus each mode's own
|
|
199
230
|
**mode-specific** realization columns. The core is what both modes actually share: `date`, `doc_key`,
|
|
200
231
|
`tier`, `model`, `findings_raised`, `findings_real`, `verdict`, `revise_rounds`.
|
|
@@ -285,6 +316,11 @@ The binding inputs, by review type:
|
|
|
285
316
|
clause reads both), and the **probe harness** (`ai_docs/solutions/harness_[feature]/`).
|
|
286
317
|
Hand these *in addition to* the design artifact — the reviewer checks the artifact
|
|
287
318
|
**against** them, not only for internal consistency.
|
|
319
|
+
- **The constraint view comes last.** Where the ANALYSIS carries ids, the reviewer
|
|
320
|
+
derives the callers and behaviours first, then compares with
|
|
321
|
+
`sdlc_check.py constraints --unit <id>`: a constraint the design states and the
|
|
322
|
+
diff breaks is a finding. The view never replaces the ANALYSIS or the diff in the
|
|
323
|
+
request.
|
|
288
324
|
- **For a closure review, the diff and the test evidence**: the run output that
|
|
289
325
|
backs every completion claim, dated after the final relevant change.
|
|
290
326
|
- **For a design or closure review of an L3/E3 unit, the request record**
|
|
@@ -615,6 +615,11 @@ class Grounds:
|
|
|
615
615
|
return [{"kind": "untraceable", "path": rel}]
|
|
616
616
|
seen = seen | {rel}
|
|
617
617
|
if rel.startswith("corpus/given/"):
|
|
618
|
+
# F-084: a document this project SENT is our own declaration, not
|
|
619
|
+
# ground for a fact about the product.
|
|
620
|
+
side = self._meta(rel + ".meta.md")
|
|
621
|
+
if _v(side, "provenance").upper() == "DECLARED":
|
|
622
|
+
return [{"kind": "declared", "path": rel}]
|
|
618
623
|
return [{"kind": "document", "path": rel}]
|
|
619
624
|
if not _inside(self.docs, rel) or not (self.docs / rel).is_file():
|
|
620
625
|
return [{"kind": "untraceable", "path": rel}]
|
|
@@ -643,6 +648,8 @@ def ground_class(leaves):
|
|
|
643
648
|
return "statement"
|
|
644
649
|
if "untraceable" in kinds:
|
|
645
650
|
return "untraceable"
|
|
651
|
+
if "declared" in kinds:
|
|
652
|
+
return "declared"
|
|
646
653
|
if "kb" in kinds:
|
|
647
654
|
return "imported"
|
|
648
655
|
return "documents"
|
|
@@ -707,12 +714,15 @@ def build_kb(docs):
|
|
|
707
714
|
kind, rest = _kind(r)
|
|
708
715
|
f = {"text": r["claim"], "valid": r["valid"], "qty": r["qty"], "about": r["about"],
|
|
709
716
|
"origin": (r["prov"] or "").strip().lower(), "topic": slug,
|
|
710
|
-
"state": {"SUPERSEDED": "superseded", "CONTESTED": "contested"
|
|
717
|
+
"state": {"SUPERSEDED": "superseded", "CONTESTED": "contested",
|
|
718
|
+
"DIVERGES": "diverges"}.get(kind, "ok")}
|
|
711
719
|
if kind == "SUPERSEDED":
|
|
712
720
|
f["successors"] = _ids(rest)
|
|
713
721
|
f["chain_ends"] = chain_ends(r["id"], by_id)
|
|
714
722
|
if kind == "CONTESTED":
|
|
715
723
|
f["with"] = _ids(rest)
|
|
724
|
+
if kind == "DIVERGES":
|
|
725
|
+
f["diverges_from"] = _ids(rest)
|
|
716
726
|
srcs = []
|
|
717
727
|
for src in r["source"].split(";"):
|
|
718
728
|
src = src.strip()
|
|
@@ -1246,7 +1256,9 @@ def chronology(docs, pages):
|
|
|
1246
1256
|
text = _text(docs / rel) if (docs / rel).is_file() else None
|
|
1247
1257
|
if text is not None:
|
|
1248
1258
|
for row in sdlc_core.parse_review_log(text)[0]:
|
|
1249
|
-
|
|
1259
|
+
# F-085: a `post-merge` row is the owner's defect report, not a review
|
|
1260
|
+
kind = "defect" if row["tier"].lower().startswith("post-merge") else "review"
|
|
1261
|
+
add(row["date"], kind, "%s — %s: %s" % (
|
|
1250
1262
|
row["doc_key"], row["tier"], row["verdict"]), rel)
|
|
1251
1263
|
for p in sorted(docs.glob("architecture/ADR_*.md")):
|
|
1252
1264
|
rel = "architecture/" + p.name
|
|
@@ -1269,7 +1281,9 @@ def chronology(docs, pages):
|
|
|
1269
1281
|
continue
|
|
1270
1282
|
if kind == "source":
|
|
1271
1283
|
name = p.name[:-len(suffix)]
|
|
1272
|
-
|
|
1284
|
+
# F-084: a DECLARED sidecar's date is the day it was SENT
|
|
1285
|
+
sent = _v(fm, "provenance").upper() == "DECLARED"
|
|
1286
|
+
add(date, "sent" if sent else kind, name, rel, source=name)
|
|
1273
1287
|
else:
|
|
1274
1288
|
add(date, kind, title_of(rel, text), rel)
|
|
1275
1289
|
# Most recent first. Within one day a document's later entry is the more recent
|