@antoneeo/mkt-agentic-sdlc-skill 0.29.0 → 0.30.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 +19 -0
- package/README.md +3 -3
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/skills/mkt-agentic-sdlc/ENFORCEMENT.md +10 -0
- package/skills/mkt-agentic-sdlc/SKILL.md +1 -1
- package/skills/mkt-agentic-sdlc/scripts/mkt_check.py +4 -4
- package/skills/mkt-agentic-sdlc/scripts/sdlc_core.py +60 -3
- package/skills/mkt-agentic-sdlc/templates.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.30.0] - 2026-11-01
|
|
4
|
+
|
|
5
|
+
### What's new
|
|
6
|
+
|
|
7
|
+
**Branches that add review rows merge without a conflict.** When two branches both add rows to the review log and your project has no merge rule for that file, merging them stops on a conflict you resolve by hand. The check the agent runs when it closes a piece of work now notices the missing rule and prints the exact line to add to `.gitattributes`, so the agent sees what to fix while it works, without anyone reading release notes. Nothing changes at session start, and the note never makes a check fail.
|
|
8
|
+
|
|
9
|
+
#### What to do
|
|
10
|
+
|
|
11
|
+
**1. Update (everyone).** The changes arrive only with the update.
|
|
12
|
+
1. Run `npm install -g @antoneeo/mkt-agentic-sdlc-skill@latest`, then `mkt-sdlc-install-skill`.
|
|
13
|
+
2. Close and reopen your agent sessions: the new version loads only at startup.
|
|
14
|
+
|
|
15
|
+
To check: `npm ls -g @antoneeo/mkt-agentic-sdlc-skill` shows 0.30.0.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- The shared validator (F-090): `check` prints a `[note]` when the review log (`<docs>/audit/reviews/REVIEW_LOG.md`) has no `merge` attribute, naming the line to add to `.gitattributes` at the repository root (`git check-attr`, with personal and system attribute files ignored; a per-clone `.git/info/attributes` still counts). A deliberate non-union driver is respected. The exit code is unchanged, and session orientation still runs no git. `mkt_check.py check` prints it too, for `mkt_docs/` or `ai_docs/`.
|
|
19
|
+
- `ENFORCEMENT.md`: «A review log git would not merge cleanly -- `check` names it» (F-090).
|
|
20
|
+
- `templates.md`: the `.gitattributes` stanza's note says `check` names a missing stanza and the line to add (F-090).
|
|
21
|
+
|
|
3
22
|
## [0.29.0] - 2026-10-31
|
|
4
23
|
|
|
5
24
|
### What's new
|
package/README.md
CHANGED
|
@@ -4,9 +4,9 @@ Evidence-First marketing planning protocol for AI coding agents (Claude Code, Ge
|
|
|
4
4
|
|
|
5
5
|
<!-- whats-new:begin -->
|
|
6
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.
|
|
7
|
+
## What's new in 0.30.0
|
|
8
8
|
|
|
9
|
-
**
|
|
9
|
+
**Branches that add review rows merge without a conflict.** When two branches both add rows to the review log and your project has no merge rule for that file, merging them stops on a conflict you resolve by hand. The check the agent runs when it closes a piece of work now notices the missing rule and prints the exact line to add to `.gitattributes`, so the agent sees what to fix while it works, without anyone reading release notes. Nothing changes at session start, and the note never makes a check fail.
|
|
10
10
|
|
|
11
11
|
#### What to do
|
|
12
12
|
|
|
@@ -14,7 +14,7 @@ Evidence-First marketing planning protocol for AI coding agents (Claude Code, Ge
|
|
|
14
14
|
1. Run `npm install -g @antoneeo/mkt-agentic-sdlc-skill@latest`, then `mkt-sdlc-install-skill`.
|
|
15
15
|
2. Close and reopen your agent sessions: the new version loads only at startup.
|
|
16
16
|
|
|
17
|
-
To check: `npm ls -g @antoneeo/mkt-agentic-sdlc-skill` shows 0.
|
|
17
|
+
To check: `npm ls -g @antoneeo/mkt-agentic-sdlc-skill` shows 0.30.0.
|
|
18
18
|
|
|
19
19
|
Full history: [CHANGELOG](https://github.com/Antoneeo/agentic-sdlc-skill/blob/main/distributions/mkt-agentic-sdlc/CHANGELOG.md)
|
|
20
20
|
<!-- whats-new:end -->
|
package/gemini-extension.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mkt-agentic-sdlc",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.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.30.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",
|
|
@@ -105,6 +105,16 @@ not see them, because the wired hook legitimately lives in the git-ignored
|
|
|
105
105
|
mechanism (Gemini today) keeps the note -- read it as the manual-reads reminder; a
|
|
106
106
|
`.codex/hooks.json` wired in a shape other than the documented one keeps it too.
|
|
107
107
|
|
|
108
|
+
**A review log git would not merge cleanly -- `check` names it (F-090).** When the docs
|
|
109
|
+
root holds `audit/reviews/REVIEW_LOG.md` and git reports no `merge` attribute for it (no
|
|
110
|
+
committed `.gitattributes` line covers it: a project set up before the stanza, a custom
|
|
111
|
+
docs root, a project below the repository root, a course project), `check` prints one
|
|
112
|
+
`[note]` with the exact line to add at the repository root. Same contract as above:
|
|
113
|
+
informational, never the exit code, never a `validate` warning. Personal attribute files
|
|
114
|
+
(except the per-clone `.git/info/attributes`) are ignored, so the note matches what a
|
|
115
|
+
teammate's clone does; a deliberate driver other
|
|
116
|
+
than `union` is respected. Session orientation does not run it: it stays zero-execution.
|
|
117
|
+
|
|
108
118
|
**Installing the package wires the hook machine-wide (F-042).** On Claude Code
|
|
109
119
|
with Python, `npm i -g` (and every update) wires a SessionStart orient hook into
|
|
110
120
|
the USER-level settings (`$CLAUDE_CONFIG_DIR/settings.json` when set, else
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mkt-agentic-sdlc
|
|
3
|
-
version: 0.
|
|
3
|
+
version: 0.30.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
|
|
@@ -751,10 +751,10 @@ def main(argv=None):
|
|
|
751
751
|
else:
|
|
752
752
|
print(f"[FAIL] {args.command}: {len(rep.errors)} error(s), {len(rep.warnings)} warning(s)")
|
|
753
753
|
if args.command == "check":
|
|
754
|
-
# This overlay REPLACES the spine's cmd_check, so the
|
|
755
|
-
#
|
|
756
|
-
#
|
|
757
|
-
sdlc_core.
|
|
754
|
+
# This overlay REPLACES the spine's cmd_check, so the check-layer notes
|
|
755
|
+
# (F-041 wiring, F-090 review-log merge) are re-attached here through
|
|
756
|
+
# their one entry point -- fail-open and informational, never the exit code.
|
|
757
|
+
sdlc_core.print_check_notes(root)
|
|
758
758
|
return code
|
|
759
759
|
|
|
760
760
|
|
|
@@ -1377,9 +1377,12 @@ def _open_units(root):
|
|
|
1377
1377
|
return units
|
|
1378
1378
|
|
|
1379
1379
|
|
|
1380
|
-
def _git_out(root, *args, timeout=30):
|
|
1380
|
+
def _git_out(root, *args, timeout=30, env=None):
|
|
1381
|
+
# `env` is merged into the inherited environment, never a replacement: a bare
|
|
1382
|
+
# dict would drop PATH and fail silently on Windows.
|
|
1381
1383
|
r = subprocess.run(["git", *args], cwd=str(root), capture_output=True, text=True,
|
|
1382
|
-
encoding="utf-8", errors="replace", timeout=timeout
|
|
1384
|
+
encoding="utf-8", errors="replace", timeout=timeout,
|
|
1385
|
+
env={**os.environ, **env} if env else None)
|
|
1383
1386
|
return r.stdout if r.returncode == 0 else None
|
|
1384
1387
|
|
|
1385
1388
|
|
|
@@ -2481,10 +2484,64 @@ def cmd_check(root, strict=False, hybrid=False, extra_validate=None, extra_secti
|
|
|
2481
2484
|
failed = any(rc for _, rc in rcs)
|
|
2482
2485
|
print(f"\ncheck: {'NOT CLEAN' if failed else 'CLEAN'} "
|
|
2483
2486
|
f"({', '.join(f'{title} rc={rc}' for title, rc in rcs)})")
|
|
2484
|
-
|
|
2487
|
+
print_check_notes(root)
|
|
2485
2488
|
return 1 if failed else 0
|
|
2486
2489
|
|
|
2487
2490
|
|
|
2491
|
+
def _attr_pattern(path):
|
|
2492
|
+
"""A .gitattributes pattern matching exactly `path`. Order matters (probed):
|
|
2493
|
+
a backslash, glob characters and a leading `#` or `!` (comment, negation)
|
|
2494
|
+
are escaped first, then the result is C-quoted when it holds whitespace,
|
|
2495
|
+
`"` or a backslash."""
|
|
2496
|
+
p = re.sub(r"([\\\[*?])", r"\\\1", path)
|
|
2497
|
+
if p.startswith(("#", "!")):
|
|
2498
|
+
p = "\\" + p
|
|
2499
|
+
if re.search(r'[\s"\\]', p):
|
|
2500
|
+
p = '"' + p.replace("\\", "\\\\").replace('"', '\\"') + '"'
|
|
2501
|
+
return p
|
|
2502
|
+
|
|
2503
|
+
|
|
2504
|
+
def review_log_union_note(root):
|
|
2505
|
+
"""F-090: the note for a review log git would not merge with union, or None.
|
|
2506
|
+
|
|
2507
|
+
Git itself is asked (`check-attr`), so patterns and nested files count;
|
|
2508
|
+
personal and system attribute files do not, so the answer is the one a
|
|
2509
|
+
teammate's clone gets. Only `unspecified` is a gap: `union` or any other
|
|
2510
|
+
driver is a choice. Residual: `.git/info/attributes` is still read. Any
|
|
2511
|
+
failure -- no git, not a work tree, timeout -- is no note: `check` never
|
|
2512
|
+
breaks on it."""
|
|
2513
|
+
try:
|
|
2514
|
+
log = ai_path(root, "audit", "reviews", "REVIEW_LOG.md")
|
|
2515
|
+
if not log.is_file():
|
|
2516
|
+
return None
|
|
2517
|
+
prefix = _git_out(root, "rev-parse", "--show-prefix", timeout=3)
|
|
2518
|
+
if prefix is None:
|
|
2519
|
+
return None
|
|
2520
|
+
rel = log.resolve().relative_to(Path(root).resolve()).as_posix()
|
|
2521
|
+
out = _git_out(root, "-c", "core.attributesFile=", "check-attr", "-z", "merge",
|
|
2522
|
+
"--", rel, timeout=3, env={"GIT_ATTR_NOSYSTEM": "1"})
|
|
2523
|
+
if out is None:
|
|
2524
|
+
return None
|
|
2525
|
+
fields = out.split("\0")
|
|
2526
|
+
if len(fields) < 3 or fields[2] != "unspecified":
|
|
2527
|
+
return None
|
|
2528
|
+
path = prefix.rstrip("\r\n") + rel # a folder may begin with a space
|
|
2529
|
+
return (f"[note] {path} has no merge attribute: two branches that both add review "
|
|
2530
|
+
"rows conflict when merged. Fix: add this line to .gitattributes at the "
|
|
2531
|
+
f"repository root: {_attr_pattern(path)} merge=union")
|
|
2532
|
+
except Exception:
|
|
2533
|
+
return None
|
|
2534
|
+
|
|
2535
|
+
|
|
2536
|
+
def print_check_notes(root):
|
|
2537
|
+
"""Every check-layer note, informational and never an exit code. The one
|
|
2538
|
+
place an overlay that replaces `check` calls, so a new note cannot miss it."""
|
|
2539
|
+
print_orient_hook_note(root)
|
|
2540
|
+
note = review_log_union_note(root)
|
|
2541
|
+
if note:
|
|
2542
|
+
print(note)
|
|
2543
|
+
|
|
2544
|
+
|
|
2488
2545
|
# --------------------------------------------------------------------- gate
|
|
2489
2546
|
|
|
2490
2547
|
# --- UserPromptSubmit reminder hook (F-046) --------------------------------
|
|
@@ -632,7 +632,7 @@ Concurrent reviews: `init` writes a `.gitattributes` stanza giving this file
|
|
|
632
632
|
Rows are date-stamped and their order carries no meaning, so a union merge keeps
|
|
633
633
|
both sides instead of asking a human to choose. It is defence in depth: without
|
|
634
634
|
git, or without the stanza, the outcome is today's — one conflict you resolve by
|
|
635
|
-
hand, never a lost row.
|
|
635
|
+
hand, never a lost row. `check` names a missing stanza and the line to add (F-090).
|
|
636
636
|
|
|
637
637
|
|
|
638
638
|
## audit/HANDOFF_[engagement].md (under the docs root) — one open workstream, its own file
|