@pareto4/pp-core 1.11.1 → 1.12.1
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/.claude-plugin/plugin.json +1 -1
- package/README.md +31 -0
- package/agents/pp-code-fixer.md +1 -1
- package/agents/pp-debug-session-manager.md +1 -1
- package/agents/pp-debugger.md +1 -1
- package/agents/pp-executor.md +20 -10
- package/agents/pp-intel-updater.md +1 -1
- package/agents/pp-phase-researcher.md +1 -1
- package/agents/pp-plan-checker.md +5 -5
- package/agents/pp-planner.md +10 -24
- package/agents/pp-project-researcher.md +1 -1
- package/agents/pp-research-synthesizer.md +1 -1
- package/agents/pp-ui-researcher.md +1 -1
- package/agents/pp-verifier.md +8 -4
- package/bin/install.js +429 -82
- package/commands/pp-autonomous.md +8 -6
- package/commands/pp-discovery-to-build.md +1 -1
- package/commands/pp-discovery.md +3 -2
- package/commands/pp-discuss-phase.md +2 -2
- package/commands/pp-execute-phase.md +3 -1
- package/commands/pp-graphify.md +5 -5
- package/commands/pp-import.md +1 -1
- package/commands/pp-map-codebase.md +1 -1
- package/commands/pp-ns-project.md +2 -3
- package/commands/pp-ns-workflow.md +1 -1
- package/commands/pp-plan-phase.md +2 -1
- package/commands/pp-verify-work.md +2 -1
- package/gemini-extension.json +1 -1
- package/hooks/dist/pp-cursor-session-start.js +2 -2
- package/hooks/dist/pp-session-state.sh +1 -1
- package/hooks/dist/pp-statusline.js +21 -2
- package/hooks/pp-cursor-session-start.js +2 -2
- package/hooks/pp-session-state.sh +1 -1
- package/hooks/pp-statusline.js +21 -2
- package/package.json +18 -5
- package/pareto-skills/pp-project-setup/SKILL.md +5 -63
- package/pp-core/bin/detect-build-commands.sh +182 -0
- package/pp-core/bin/lib/capability-activation.cjs +19 -9
- package/pp-core/bin/lib/capability-registry.cjs +65 -7
- package/pp-core/bin/lib/check-command-router.cjs +79 -38
- package/pp-core/bin/lib/clusters.cjs +2 -3
- package/pp-core/bin/lib/command-aliases.cjs +36 -0
- package/pp-core/bin/lib/command-arg-projection.cjs +99 -1
- package/pp-core/bin/lib/commands.cjs +21 -6
- package/pp-core/bin/lib/compose-bindings.cjs +70 -6
- package/pp-core/bin/lib/config-loader.cjs +151 -8
- package/pp-core/bin/lib/config-schema.cjs +16 -0
- package/pp-core/bin/lib/config.cjs +142 -27
- package/pp-core/bin/lib/core-utils.cjs +43 -7
- package/pp-core/bin/lib/discovery-input-check.cjs +218 -0
- package/pp-core/bin/lib/discovery-rebaseline.cjs +1372 -0
- package/pp-core/bin/lib/discovery-research-track.cjs +979 -0
- package/pp-core/bin/lib/discovery-rollup.cjs +476 -0
- package/pp-core/bin/lib/discovery-screens.cjs +1995 -0
- package/pp-core/bin/lib/discovery-sweep.cjs +390 -0
- package/pp-core/bin/lib/discovery-table.cjs +98 -0
- package/pp-core/bin/lib/dispatch-plan.cjs +472 -0
- package/pp-core/bin/lib/frontmatter.cjs +17 -2
- package/pp-core/bin/lib/init-command-router.cjs +8 -5
- package/pp-core/bin/lib/init-contract.cjs +93 -4
- package/pp-core/bin/lib/init.cjs +124 -134
- package/pp-core/bin/lib/install-profiles.cjs +5 -0
- package/pp-core/bin/lib/install-run.cjs +536 -0
- package/pp-core/bin/lib/io.cjs +15 -0
- package/pp-core/bin/lib/loop-resolver.cjs +40 -2
- package/pp-core/bin/lib/milestone.cjs +345 -48
- package/pp-core/bin/lib/phase-command-router.cjs +23 -1
- package/pp-core/bin/lib/phase-locator.cjs +15 -6
- package/pp-core/bin/lib/phase-scope.cjs +91 -0
- package/pp-core/bin/lib/phase-tier.cjs +467 -0
- package/pp-core/bin/lib/phase.cjs +247 -21
- package/pp-core/bin/lib/phases-command-router.cjs +2 -0
- package/pp-core/bin/lib/plan-graph.cjs +368 -0
- package/pp-core/bin/lib/planning-workspace.cjs +53 -0
- package/pp-core/bin/lib/platform-bindings.cjs +32 -2
- package/pp-core/bin/lib/profile-output.cjs +11 -3
- package/pp-core/bin/lib/prohibition-enforcement.cjs +112 -0
- package/pp-core/bin/lib/roadmap-parser.cjs +366 -99
- package/pp-core/bin/lib/roadmap.cjs +141 -39
- package/pp-core/bin/lib/runtime-hooks-surface.cjs +1 -1
- package/pp-core/bin/lib/shell-command-projection.cjs +24 -0
- package/pp-core/bin/lib/state-command-router.cjs +82 -13
- package/pp-core/bin/lib/state-document.cjs +124 -7
- package/pp-core/bin/lib/state.cjs +784 -257
- package/pp-core/bin/lib/template.cjs +22 -6
- package/pp-core/bin/lib/vault-command-router.cjs +57 -6
- package/pp-core/bin/lib/vault-practices.cjs +6 -36
- package/pp-core/bin/lib/vault-write-back.cjs +20 -4
- package/pp-core/bin/lib/vault.cjs +592 -23
- package/pp-core/bin/lib/verify.cjs +53 -31
- package/pp-core/bin/lib/workstream.cjs +1 -1
- package/pp-core/bin/lib/worktree-safety.cjs +26 -15
- package/pp-core/bin/portable-timeout.sh +89 -0
- package/pp-core/bin/pp-tools.cjs +149 -9
- package/pp-core/bin/shared/config-defaults.manifest.json +7 -0
- package/pp-core/bin/shared/config-schema.manifest.json +3 -0
- package/pp-core/references/autonomous-best-effort.md +461 -0
- package/pp-core/references/autonomous-lifecycle.md +146 -0
- package/pp-core/references/autonomous-smart-discuss.md +16 -12
- package/pp-core/references/checkpoints.md +1 -1
- package/pp-core/references/discovery-id-conventions.md +202 -0
- package/pp-core/references/discovery-rebaseline.md +254 -0
- package/pp-core/references/discovery-research-track.md +283 -0
- package/pp-core/references/discovery-traceability.md +400 -0
- package/pp-core/references/loop-hook-dispatch.md +14 -0
- package/pp-core/references/mandatory-initial-read.md +1 -1
- package/pp-core/references/planner-gap-closure.md +1 -0
- package/pp-core/references/planner-human-verify-mode.md +1 -1
- package/pp-core/references/planner-load-graph-context.md +1 -1
- package/pp-core/references/planner-plan-graph.md +66 -0
- package/pp-core/references/planner-tdd.md +1 -0
- package/pp-core/references/planning-config.md +8 -0
- package/pp-core/references/sketch-tooling.md +4 -0
- package/pp-core/references/tdd.md +1 -0
- package/pp-core/templates/claude-md.md +1 -1
- package/pp-core/templates/phase-prompt.md +6 -2
- package/pp-core/templates/prototype-review/review.js +303 -0
- package/pp-core/templates/state.md +6 -0
- package/pp-core/workflows/_runtime-launcher.snippet.sh +1 -1
- package/pp-core/workflows/add-backlog.md +1 -1
- package/pp-core/workflows/add-phase.md +1 -1
- package/pp-core/workflows/add-tests.md +1 -1
- package/pp-core/workflows/add-todo.md +1 -1
- package/pp-core/workflows/ai-integration-phase.md +2 -2
- package/pp-core/workflows/audit-fix.md +12 -16
- package/pp-core/workflows/audit-milestone.md +2 -2
- package/pp-core/workflows/audit-uat.md +1 -1
- package/pp-core/workflows/autonomous.md +68 -306
- package/pp-core/workflows/check-todos.md +1 -1
- package/pp-core/workflows/cleanup.md +1 -1
- package/pp-core/workflows/code-review-fix.md +2 -2
- package/pp-core/workflows/code-review.md +20 -8
- package/pp-core/workflows/complete-milestone.md +41 -60
- package/pp-core/workflows/debug.md +1 -1
- package/pp-core/workflows/diagnose-issues.md +1 -1
- package/pp-core/workflows/discovery-sprint/gap-analysis.md +140 -0
- package/pp-core/workflows/discovery-sprint/input-package.md +140 -0
- package/pp-core/workflows/discovery-sprint/prefill.md +92 -0
- package/pp-core/workflows/discovery-sprint/prototype.md +257 -0
- package/pp-core/workflows/discovery-sprint/rebaseline.md +276 -0
- package/pp-core/workflows/discovery-sprint/session-13-gates.md +24 -0
- package/pp-core/workflows/discovery-sprint/sessions/01-kick-off.md +92 -0
- package/pp-core/workflows/discovery-sprint/sessions/02-as-is.md +98 -0
- package/pp-core/workflows/discovery-sprint/sessions/03-to-be.md +215 -0
- package/pp-core/workflows/discovery-sprint/sessions/04-ux-design.md +146 -0
- package/pp-core/workflows/discovery-sprint/sessions/05-architecture.md +98 -0
- package/pp-core/workflows/discovery-sprint/sessions/06-security.md +107 -0
- package/pp-core/workflows/discovery-sprint/sessions/07-identity.md +98 -0
- package/pp-core/workflows/discovery-sprint/sessions/08-integration.md +85 -0
- package/pp-core/workflows/discovery-sprint/sessions/09-qa.md +109 -0
- package/pp-core/workflows/discovery-sprint/sessions/10-infrastructure.md +119 -0
- package/pp-core/workflows/discovery-sprint/sessions/11-roadmap.md +92 -0
- package/pp-core/workflows/discovery-sprint/sessions/12-delivery-model.md +98 -0
- package/pp-core/workflows/discovery-sprint/sessions/13-wrap-up.md +205 -0
- package/pp-core/workflows/discovery-sprint/templates/context-template.md +266 -0
- package/pp-core/workflows/discovery-sprint.md +79 -1714
- package/pp-core/workflows/discovery-to-build/steps/architecture-deliverables.md +5 -5
- package/pp-core/workflows/discovery-to-build/steps/screen-inventory-gate.md +70 -0
- package/pp-core/workflows/discovery-to-build/templates/discovery-references.md +54 -0
- package/pp-core/workflows/discovery-to-build/templates/pp-handoff.md +184 -0
- package/pp-core/workflows/discovery-to-build.md +21 -238
- package/pp-core/workflows/discuss-phase/modes/advisor.md +1 -1
- package/pp-core/workflows/discuss-phase/modes/auto.md +1 -1
- package/pp-core/workflows/discuss-phase/modes/chain.md +1 -1
- package/pp-core/workflows/discuss-phase-assumptions.md +1 -1
- package/pp-core/workflows/discuss-phase.md +11 -4
- package/pp-core/workflows/do.md +4 -4
- package/pp-core/workflows/docs-update.md +1 -1
- package/pp-core/workflows/edit-phase.md +1 -1
- package/pp-core/workflows/eval-review.md +1 -1
- package/pp-core/workflows/execute-phase/steps/checkpoint-handling.md +45 -0
- package/pp-core/workflows/execute-phase/steps/client-context-gate.md +1 -1
- package/pp-core/workflows/execute-phase/steps/codebase-drift-gate.md +1 -1
- package/pp-core/workflows/execute-phase/steps/cross-ai-delegation.md +90 -0
- package/pp-core/workflows/execute-phase/steps/install-run.md +29 -0
- package/pp-core/workflows/execute-phase/steps/phase-close-rebaseline.md +23 -0
- package/pp-core/workflows/execute-phase/steps/post-merge-gate.md +76 -77
- package/pp-core/workflows/execute-phase/steps/serial-group-dispatch.md +72 -0
- package/pp-core/workflows/execute-phase/steps/vault-fetch.md +5 -5
- package/pp-core/workflows/execute-phase/steps/vault-load-gate.md +19 -112
- package/pp-core/workflows/execute-phase.md +104 -218
- package/pp-core/workflows/execute-plan.md +6 -2
- package/pp-core/workflows/explore.md +1 -1
- package/pp-core/workflows/extract-learnings.md +1 -1
- package/pp-core/workflows/forensics.md +4 -4
- package/pp-core/workflows/graduation.md +1 -1
- package/pp-core/workflows/health.md +1 -1
- package/pp-core/workflows/help/modes/brief.md +1 -0
- package/pp-core/workflows/help/modes/default.md +2 -1
- package/pp-core/workflows/help/modes/full.md +12 -5
- package/pp-core/workflows/import.md +1 -1
- package/pp-core/workflows/ingest-docs.md +1 -1
- package/pp-core/workflows/init.md +18 -2
- package/pp-core/workflows/insert-phase.md +1 -1
- package/pp-core/workflows/list-workspaces.md +1 -1
- package/pp-core/workflows/manager.md +3 -3
- package/pp-core/workflows/map-codebase.md +2 -2
- package/pp-core/workflows/milestone-summary.md +4 -4
- package/pp-core/workflows/mvp-phase.md +1 -1
- package/pp-core/workflows/new-milestone.md +7 -8
- package/pp-core/workflows/new-project.md +6 -1
- package/pp-core/workflows/new-workspace.md +1 -1
- package/pp-core/workflows/next.md +2 -2
- package/pp-core/workflows/note.md +2 -2
- package/pp-core/workflows/pause-work.md +1 -1
- package/pp-core/workflows/plan-milestone-gaps.md +1 -1
- package/pp-core/workflows/plan-phase/steps/chunked-planning.md +111 -0
- package/pp-core/workflows/plan-phase/steps/phase-tier.md +34 -0
- package/pp-core/workflows/plan-phase.md +43 -167
- package/pp-core/workflows/plan-review-convergence.md +2 -2
- package/pp-core/workflows/plant-seed.md +1 -1
- package/pp-core/workflows/pr-branch.md +1 -1
- package/pp-core/workflows/profile-user.md +1 -1
- package/pp-core/workflows/progress.md +3 -3
- package/pp-core/workflows/quick.md +4 -2
- package/pp-core/workflows/remove-phase.md +1 -1
- package/pp-core/workflows/remove-workspace.md +1 -1
- package/pp-core/workflows/resume-project.md +6 -12
- package/pp-core/workflows/review.md +1 -1
- package/pp-core/workflows/scan.md +1 -1
- package/pp-core/workflows/secure-phase.md +2 -2
- package/pp-core/workflows/settings-advanced.md +1 -1
- package/pp-core/workflows/settings-integrations.md +1 -1
- package/pp-core/workflows/settings.md +1 -1
- package/pp-core/workflows/ship.md +26 -9
- package/pp-core/workflows/sketch-wrap-up.md +1 -1
- package/pp-core/workflows/sketch.md +2 -1
- package/pp-core/workflows/spec-phase.md +1 -1
- package/pp-core/workflows/spike-wrap-up.md +1 -1
- package/pp-core/workflows/spike.md +1 -1
- package/pp-core/workflows/stats.md +2 -2
- package/pp-core/workflows/thread.md +1 -1
- package/pp-core/workflows/transition.md +5 -9
- package/pp-core/workflows/ui-phase.md +23 -2
- package/pp-core/workflows/ui-review.md +1 -1
- package/pp-core/workflows/ultraplan-phase.md +2 -2
- package/pp-core/workflows/validate-phase.md +2 -2
- package/pp-core/workflows/vault-write-back.md +1 -1
- package/pp-core/workflows/verify-phase.md +29 -26
- package/pp-core/workflows/verify-work.md +14 -10
- package/scripts/base64-scan.sh +7 -41
- package/scripts/changeset/cli.cjs +25 -5
- package/scripts/dev-env.cjs +462 -0
- package/scripts/lib/allowlist-ratchet.cjs +103 -1
- package/scripts/lib/size-budget.cjs +311 -0
- package/scripts/lint-neutrality-names.cjs +694 -0
- package/scripts/lint-org-coordinates.allowlist.json +35 -0
- package/scripts/lint-org-coordinates.cjs +426 -0
- package/scripts/lint-skill-deps.cjs +48 -9
- package/scripts/lint-test-file-count.cjs +17 -2
- package/scripts/prompt-injection-scan.sh +41 -20
- package/scripts/sync-manifest-versions.cjs +41 -7
- package/scripts/sync-runtime-launcher.cjs +106 -1
- package/scripts/update-size-baseline.cjs +274 -30
- package/scripts/workflow-size.cjs +61 -9
- package/commands/pp-build-handoff.md +0 -46
- package/pp-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +0 -94
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Discovery input-package enforcement engine (discovery-v2 Phase 2,
|
|
4
|
+
* INPUT-02/INPUT-03, D-18/D-19/D-22).
|
|
5
|
+
*
|
|
6
|
+
* Scans the per-engagement `.planning/discovery/session-NN.md` files and the
|
|
7
|
+
* confidential input directory, failing loud (D-19) when:
|
|
8
|
+
* - a session is `Completed` while `[TO CONFIRM]` markers remain in its
|
|
9
|
+
* body (completed_with_unconfirmed), or
|
|
10
|
+
* - a completeness_score of 100 counts unconfirmed topics — markers remain,
|
|
11
|
+
* or the session is still `Pre-Filled` (score_counts_unconfirmed; D-18:
|
|
12
|
+
* Pre-Filled is not Completed), or
|
|
13
|
+
* - git tracks any file under `.planning/discovery-input/confidential/`
|
|
14
|
+
* (confidential_tracked — the D-22 mechanical backstop), with a single
|
|
15
|
+
* designed exception: the backstop `confidential/.gitignore` itself is
|
|
16
|
+
* exempt — it is written to be committed (UAT gap 1).
|
|
17
|
+
*
|
|
18
|
+
* Graceful arms (Pitfall 4 / RESEARCH A3): a non-git project, a project with
|
|
19
|
+
* no `.planning/discovery/` directory, and a session without a frontmatter
|
|
20
|
+
* block all pass clean — the check fails only on real violations.
|
|
21
|
+
*
|
|
22
|
+
* Content-free contract (T-02-05): output names file paths, structured
|
|
23
|
+
* reasons, and counts only — never file contents.
|
|
24
|
+
*/
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
29
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
30
|
+
const node_child_process_1 = require("node:child_process");
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
32
|
+
const io = require("./io.cjs");
|
|
33
|
+
const { output, error, ERROR_REASON } = io;
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
35
|
+
const fm = require("./frontmatter.cjs");
|
|
36
|
+
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
37
|
+
const SESSION_STATUS = Object.freeze({
|
|
38
|
+
NOT_STARTED: 'Not Started',
|
|
39
|
+
PRE_FILLED: 'Pre-Filled',
|
|
40
|
+
IN_PROGRESS: 'In Progress',
|
|
41
|
+
COMPLETED: 'Completed',
|
|
42
|
+
});
|
|
43
|
+
const TO_CONFIRM_MARKER = '[TO CONFIRM]';
|
|
44
|
+
const CONFIDENTIAL_DIR = '.planning/discovery-input/confidential/';
|
|
45
|
+
// UAT gap 1 / D-22: input-package.md Step 4 writes this file with `*` +
|
|
46
|
+
// `!.gitignore` so the confidentiality backstop travels with the repo; the
|
|
47
|
+
// gate must accept its own designed state, else Step 6 remediation would
|
|
48
|
+
// strip protection from fresh clones. `git ls-files` emits forward-slash
|
|
49
|
+
// relative paths on every platform, so strict `===` equality is correct.
|
|
50
|
+
const CONFIDENTIAL_BACKSTOP = `${CONFIDENTIAL_DIR}.gitignore`;
|
|
51
|
+
const DISCOVERY_DIR = '.planning/discovery';
|
|
52
|
+
const GIT_TIMEOUT_MS = 5000;
|
|
53
|
+
// Anchored fixed-shape filename filter (threat T-02-07): never a regex over
|
|
54
|
+
// untrusted session content — content scanning is literal-only below.
|
|
55
|
+
const SESSION_FILE_RE = /^session-\d{2}\.md$/;
|
|
56
|
+
// Frontmatter block at byte 0 — same shape extractFrontmatter recognizes, so
|
|
57
|
+
// the body slice stays in lockstep with what the parser consumed.
|
|
58
|
+
const FRONTMATTER_BLOCK_RE = /^---\r?\n[\s\S]+?\r?\n---/;
|
|
59
|
+
// ─── Session content check (D-18/D-19) ────────────────────────────────────────
|
|
60
|
+
/**
|
|
61
|
+
* Check one session file's content for pre-fill violations. Pure.
|
|
62
|
+
*
|
|
63
|
+
* Marker counting scans only the body (content after the closing frontmatter
|
|
64
|
+
* delimiter) via literal split on TO_CONFIRM_MARKER — zero regex over
|
|
65
|
+
* untrusted content (T-02-07), counts every occurrence. A session without a
|
|
66
|
+
* frontmatter block is not pre-filled (A3) and returns no violations. A
|
|
67
|
+
* session can carry both violation kinds.
|
|
68
|
+
*/
|
|
69
|
+
function checkSessionContent(name, content) {
|
|
70
|
+
const violations = [];
|
|
71
|
+
if (typeof content !== 'string' || content.length === 0)
|
|
72
|
+
return violations;
|
|
73
|
+
const front = fm.extractFrontmatter(content);
|
|
74
|
+
if (Object.keys(front).length === 0)
|
|
75
|
+
return violations;
|
|
76
|
+
const blockMatch = FRONTMATTER_BLOCK_RE.exec(content);
|
|
77
|
+
const body = blockMatch ? content.slice(blockMatch[0].length) : content;
|
|
78
|
+
const markers = body.split(TO_CONFIRM_MARKER).length - 1;
|
|
79
|
+
const status = typeof front.status === 'string' ? front.status : '';
|
|
80
|
+
const scoreRaw = front.completeness_score;
|
|
81
|
+
const score = typeof scoreRaw === 'string' && scoreRaw.trim() !== '' ? Number(scoreRaw) : NaN;
|
|
82
|
+
// D-19: a Completed session must have zero unconfirmed markers.
|
|
83
|
+
if (status === SESSION_STATUS.COMPLETED && markers > 0) {
|
|
84
|
+
violations.push({ session: name, reason: 'completed_with_unconfirmed', markers });
|
|
85
|
+
}
|
|
86
|
+
// D-18/D-19: a score of 100 may never count unconfirmed topics — markers
|
|
87
|
+
// remain (any status) or the session never left Pre-Filled.
|
|
88
|
+
if ((markers > 0 && score === 100) || (status === SESSION_STATUS.PRE_FILLED && score === 100)) {
|
|
89
|
+
violations.push({ session: name, reason: 'score_counts_unconfirmed', score: 100, markers });
|
|
90
|
+
}
|
|
91
|
+
return violations;
|
|
92
|
+
}
|
|
93
|
+
// ─── Confidential backstop (D-22) ─────────────────────────────────────────────
|
|
94
|
+
/**
|
|
95
|
+
* Ask git for tracked files under the confidential directory. Array args,
|
|
96
|
+
* fixed literal path, no shell, bounded timeout (threat T-02-04; T-01-08
|
|
97
|
+
* precedent). Any failure — non-git directory, missing git binary, timeout —
|
|
98
|
+
* degrades to zero tracked files with git flagged unavailable: a non-git
|
|
99
|
+
* project cannot track anything (Pitfall 4).
|
|
100
|
+
*/
|
|
101
|
+
function findTrackedConfidentialInternal(cwd) {
|
|
102
|
+
try {
|
|
103
|
+
const stdout = (0, node_child_process_1.execFileSync)('git', ['ls-files', '--', CONFIDENTIAL_DIR], {
|
|
104
|
+
cwd,
|
|
105
|
+
encoding: 'utf-8',
|
|
106
|
+
timeout: GIT_TIMEOUT_MS,
|
|
107
|
+
windowsHide: true, // #685: no console-window flash on Windows
|
|
108
|
+
});
|
|
109
|
+
return { files: stdout.split(/\r?\n/).map(l => l.trim()).filter(Boolean), git: 'ok' };
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return { files: [], git: 'unavailable' };
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/** Public form of the D-22 backstop: tracked confidential paths, [] when none or non-git. */
|
|
116
|
+
function findTrackedConfidential(cwd) {
|
|
117
|
+
return findTrackedConfidentialInternal(cwd).files;
|
|
118
|
+
}
|
|
119
|
+
// ─── Package aggregation ──────────────────────────────────────────────────────
|
|
120
|
+
/**
|
|
121
|
+
* Aggregate the full input-package check for a project root: every
|
|
122
|
+
* `.planning/discovery/session-NN.md` runs through checkSessionContent, and
|
|
123
|
+
* each git-tracked confidential file appends a confidential_tracked
|
|
124
|
+
* violation — except the one designed path, the backstop `.gitignore`
|
|
125
|
+
* itself (exact-path exemption, UAT gap 1 / D-22). Missing discovery dir →
|
|
126
|
+
* ok:true with sessions_checked 0.
|
|
127
|
+
*/
|
|
128
|
+
function checkInputPackage(cwd) {
|
|
129
|
+
const violations = [];
|
|
130
|
+
let names = [];
|
|
131
|
+
try {
|
|
132
|
+
names = node_fs_1.default.readdirSync(node_path_1.default.join(cwd, DISCOVERY_DIR));
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
names = []; // no input package — graceful arm (Pitfall 4)
|
|
136
|
+
}
|
|
137
|
+
const sessions = names.filter(n => SESSION_FILE_RE.test(n)).sort();
|
|
138
|
+
let prefilled = 0;
|
|
139
|
+
for (const name of sessions) {
|
|
140
|
+
let content = '';
|
|
141
|
+
try {
|
|
142
|
+
content = node_fs_1.default.readFileSync(node_path_1.default.join(cwd, DISCOVERY_DIR, name), 'utf-8');
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
continue; // unreadable session: nothing to scan, nothing to fail on
|
|
146
|
+
}
|
|
147
|
+
const front = fm.extractFrontmatter(content);
|
|
148
|
+
const status = typeof front.status === 'string' ? front.status : '';
|
|
149
|
+
const mode = typeof front.mode === 'string' ? front.mode : '';
|
|
150
|
+
if (status === SESSION_STATUS.PRE_FILLED || mode === 'pre-fill')
|
|
151
|
+
prefilled += 1;
|
|
152
|
+
violations.push(...checkSessionContent(name, content));
|
|
153
|
+
}
|
|
154
|
+
const tracked = findTrackedConfidentialInternal(cwd);
|
|
155
|
+
for (const file of tracked.files) {
|
|
156
|
+
// Violation-policy exemption, not a git-truth change: findTrackedConfidential
|
|
157
|
+
// still reports the backstop path; only the exact designed path is skipped.
|
|
158
|
+
if (file === CONFIDENTIAL_BACKSTOP)
|
|
159
|
+
continue;
|
|
160
|
+
violations.push({ file, reason: 'confidential_tracked' });
|
|
161
|
+
}
|
|
162
|
+
const summary = {
|
|
163
|
+
sessions_checked: sessions.length,
|
|
164
|
+
prefilled,
|
|
165
|
+
git: tracked.git,
|
|
166
|
+
};
|
|
167
|
+
if (violations.length > 0)
|
|
168
|
+
return { ok: false, violations, ...summary };
|
|
169
|
+
return { ok: true, ...summary };
|
|
170
|
+
}
|
|
171
|
+
// ─── CLI adapter ──────────────────────────────────────────────────────────────
|
|
172
|
+
/** One content-free line per violation: path + structured reason + counts (T-02-05). */
|
|
173
|
+
function formatViolation(v) {
|
|
174
|
+
if (v.reason === 'confidential_tracked') {
|
|
175
|
+
return ` ${v.file}: confidential_tracked`;
|
|
176
|
+
}
|
|
177
|
+
const score = v.reason === 'score_counts_unconfirmed' ? `score: ${v.score}, ` : '';
|
|
178
|
+
return ` ${v.session}: ${v.reason} (${score}markers: ${v.markers})`;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* CLI adapter for `pp-tools discovery input-check` (dotted form
|
|
182
|
+
* `pp-tools query discovery.input-check`).
|
|
183
|
+
*
|
|
184
|
+
* Exit semantics (D-19/D-22): any violation exits non-zero via
|
|
185
|
+
* ERROR_REASON.DISCOVERY_INPUT_CHECK_FAILED, naming each violation by path
|
|
186
|
+
* and reason — never file contents. A clean run exits 0 with
|
|
187
|
+
* { ok, sessions_checked, prefilled, git }. The command takes no positional
|
|
188
|
+
* path argument — fixed convention paths resolve against cwd, eliminating
|
|
189
|
+
* the traversal surface entirely (T-02-08).
|
|
190
|
+
*/
|
|
191
|
+
function cmdDiscoveryInputCheck(cwd, args, raw) {
|
|
192
|
+
// args arrive shaped ['discovery', 'input-check', ...]; global output
|
|
193
|
+
// flags are consumed by the dispatcher, so anything left is a usage error.
|
|
194
|
+
if (args.slice(2).length > 0) {
|
|
195
|
+
error('Usage: pp-tools discovery input-check', ERROR_REASON.USAGE);
|
|
196
|
+
return; // unreachable — error() exits
|
|
197
|
+
}
|
|
198
|
+
const result = checkInputPackage(cwd);
|
|
199
|
+
if (!result.ok) {
|
|
200
|
+
const lines = result.violations.map(formatViolation).join('\n');
|
|
201
|
+
error(`discovery input-check: ${result.violations.length} violation(s):\n${lines}`, ERROR_REASON.DISCOVERY_INPUT_CHECK_FAILED);
|
|
202
|
+
return; // unreachable — error() exits
|
|
203
|
+
}
|
|
204
|
+
output({
|
|
205
|
+
ok: true,
|
|
206
|
+
sessions_checked: result.sessions_checked,
|
|
207
|
+
prefilled: result.prefilled,
|
|
208
|
+
git: result.git,
|
|
209
|
+
}, raw);
|
|
210
|
+
}
|
|
211
|
+
module.exports = {
|
|
212
|
+
SESSION_STATUS,
|
|
213
|
+
TO_CONFIRM_MARKER,
|
|
214
|
+
checkSessionContent,
|
|
215
|
+
findTrackedConfidential,
|
|
216
|
+
checkInputPackage,
|
|
217
|
+
cmdDiscoveryInputCheck,
|
|
218
|
+
};
|